UVA:11709 - Trust groups( Tarjan SCC )


UVA: 11709 - Trust groups

IDEA: 
The problem is asking the minimum number of stable groups that can be created.
This is same as finding strongly connected component (SSC) in directed graph.
Here is the basic code of Tarjan algorithm for finding SSC, which works on O(V+E).

///============================================================================///
/// ///
/// IT'S ME ///
/// BISHAL GAUTAM ///
/// CSE,JAHANGIRNAGAR UNIVERSITY,DHAKA ///
/// "Follow Excellence..Success will chase U" ///
/// ///
///============================================================================///
#include<bits/stdc++.h>
#define PI acos(-1.0)
#define X first
#define Y second
#define mpp make_pair
#define nl printf("\n")
#define SZ(x) (int)(x.size())
#define pb(x) push_back(x)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pdd pair<double,double>

///==Scanning====///
#define S(a) scanf("%d",&a)
#define P(a) printf("%d",a)
#define SL(a) scanf("%lld",&a)
#define S2(a,b) scanf("%d%d",&a,&b)
#define S3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define SL2(a,b) scanf("%lld%lld",&a,&b)
#define SL3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)

///==Arr,Vec Functions==///
#define all(v) v.begin(),v.end()
#define CLR(a) memset(a,0,sizeof(a))
#define SET(a) memset(a,-1,sizeof(a))
#define CPY(a,b) memcpy(a,b,sizeof(a))
#define MAX(a) (*max_element(all(a)))
#define MIN(a) (*min_element(all(a)))
#define fv(i,v) for(int i=0;i<(int)v.size();i++)
#define fr(i,a,n) for(int i=a;i<=n;i++)
#define rf(i,n,a) for(int i=n;i>=a;i--)

///===Some Useful====///
#define OnBit(a) __builtin_popcountll((ll)a)
#define LB(v,k) lower_bound(v.begin(),v.end(),k)
#define _cin ios_base::sync_with_stdio(0),cin.tie(0)
#define dbg(x) cerr<<__LINE__<< ":: "<<#x<<"= "<<x<<endl
#define UNIK(v) sort(all(v)),v.resize( unique(all(v)) -v.begin() );
#define fi(n) for(__typeof(n.begin()) it=n.begin();it!=n.end();it++)
#define IO freopen("A.in","r",stdin),freopen("Out.out","w",stdout)
using namespace std;

///===TypeDefs=====///
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vll;
typedef vector<pii> vii;

///===Number Theory===///
//template< class T > inline T SQR(T a) { return ((a)*(a)); }
//template< class T > inline T gcd(T a,T b) {a=abs(a);b=abs(b); if(!b) return a; return gcd(b,a%b);}
//template< class T > inline T lcm(T a,T b) {a=abs(a);b=abs(b); return (a/_gcd(a,b))*b;}
//template<typename T> T POW(T b,T p) {T r=1; while(p){if(p&1)r=(r*b);b=(b*b);p>>=1;}return r;}
//template<typename T> T BigMod(T b,T p,T m) {T r=1; while(p){if(p&1)r=(r*b)%m;b=(b*b)%m;p>>=1;}return r;}
//template<typename T> T ModInverse(T n,T m) { return BigMod(n,m-2,m); }
//
/////==GeoMetry=========///
//double DEG(double x) { return (180.0*x)/(PI);}
//double RAD(double x) { return (x*(double)PI)/(180.0);}
//template<typename T> double DIS(T a,T b){ return sqrt((double)( SQR(a.X-b.X)+ SQR(a.Y-b.Y))); }
//template<typename T> T ANGLE(T a,T b){ return atan( double(a.Y-b.Y) / double(a.X-b.X));}
//template<typename T> int isLeft(T a,T b,T c) { return (c.X-a.X)*(b.Y-a.Y)-(b.X-a.X)*(c.Y-a.Y); }
//
/////===IO-Related===///
//template< class T > void prnt(T v) { fv(i,v) {if(!i)cout<<v[i];else cout<<" "<<v[i];} cout<<endl; }
//template< class T > void BIN(T n) { if(!n){nl;return;}BIN(n/2);cout<<(n%2); }

///====Some-Stuff===///
/// atoi( str.c_str() ); // char string to int
/// sprintf(str,"%d",num);// num to char string
///int month[]={-1,31,28,31,30,31,30,31,31,30,31,30,31}; //Not Leap Year
///int dx[]={1,0,-1,0};int dy[]={0,1,0,-1}; //4 Direction
///int dx[]={1,1,0,-1,-1,-1,0,1};int dy[]={0,1,1,1,0,-1,-1,-1};//8 Direction
///int dx[]={2,1,-1,-2,-2,-1,1,2};int dy[]={1,2,2,1,-1,-2,-2,-1};//Knight Direction

/**************************************************************************************
* ///////////////////////////////////////////////////////////////////////////////////*
*************************************************************************************/

///==========CONSTANTS==============///
/// Digit 0123456789*#@%&^$"- ///
#define MX 1005
#define MXX 12500005
#define inf 2000000000
#define MD 1000000007LL
#define eps 1e-9
///================================///

vector<int>G[MX+2];
int n,tmm=0,St[MX+2],low[MX+2];
int Cp[MX+2],cm,Stk[MX+2],tp;

void Tarjan(int u) {
St[u]=low[u]=++tmm;
Stk[tp++]=u;
for(int i=0; i<SZ(G[u]); i++) {
int v=G[u][i];
if(!St[v]) {
Tarjan(v);
low[u]=min(low[u],low[v]);
} else if(!Cp[v]) {
low[u]=min(low[u],St[v]);
}
}
if(St[u]==low[u]) {
++cm;
while(true) {
int xx=Stk[--tp];
Cp[ xx ]=cm;/// Comp of xx => cm
if( xx==u )break;
}
}
}

void Find_SSC( ) {
CLR(St);
CLR(Cp);
cm=tmm=tp=0;///tot comp,dfs time & stk ptr
for(int i=1; i<=n; i++) {
if(!St[i])Tarjan(i);
}
}

map<string,int>MP;
int main() {
int tc,cs=1,i,j,k,m,x,y;
while( S2(n,m)==2 && (n+m) ) {
getchar();
fr(i,1,n) {
string s;
getline(cin,s);
MP[ s ]=i;
G[ i ].clear();
}
fr(i,1,m) {
string a,b;
getline(cin,a);
getline(cin,b);
x=MP[a],y=MP[b];
G[ x ].pb( y );
}
Find_SSC( );
printf("%d\n",cm);
}
return 0;
}

Comments

Popular posts from this blog

HackerEarth: City and Campers 2 (DSU-UnionFind)

Two Pointers Technique & Binary Search For Beginners

Problem : Codeforces Round #406 (Div. 1) B [ Legacy ]( Dijakstra, Segment tree)