http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1128
这道题是裸的强连通分量,之前没有写类似的题,所以敲的很辛苦。
/*Accepted 920 KB 32 ms C++ 2240 B 2012-07-28 16:54:39*/ #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int MAXN = 1 << 7; struct edge { int v, n; } e[MAXN *MAXN]; int first[MAXN], es; void addedge(int u, int v) { e[es].v = v, e[es].n = first[u], first[u] = es++; } int n, m, tu, tv, ans; int dfn[MAXN], low[MAXN], col[MAXN], stk[MAXN], ins[MAXN], ind, top, cols, tmp; int indg[MAXN], outdg[MAXN], zeroin, zeroout; void dfs(int u) { dfn[u] = low[u] = ++ind; stk[++top] = u, ins[u] = 1; for(int i = first[u]; i != -1; i = e[i].n) { int v = e[i].v; if( dfn[v] == 0) { dfs(v); if(low[v] < low[u]) low[u] = low[v]; } else if(ins[v]) { if(dfn[v] < low[u]) low[u] = dfn[v]; } } if(dfn[u] == low[u]) { cols++; do { tmp = stk[top--]; col[tmp] = cols; ins[tmp] = 0; }while(tmp != u); } } void tarjan( int n) { memset(dfn, 0, sizeof dfn); memset(low, 0, sizeof low); memset(col, 0, sizeof col); memset(stk, 0, sizeof stk); memset(ins, 0, sizeof ins); ind = top = cols = 0; for(int i = 1; i <= n; i++) { if( dfn[i] == 0) dfs(i); } if(cols == 1) { ans = 0; return; } ans = zeroin = zeroout = 0; memset(indg, 0, sizeof indg); memset(outdg, 0, sizeof outdg); for(int u = 1; u <= n; u++) { for(int i = first[u]; i != -1; i = e[i].n) { int v = e[i].v; if(col[u] == col[v])continue; indg[col[v]]++; outdg[col[u]]++; } } for(int i = 1; i <= cols; i++) { if(indg[i] == 0)zeroin++; if(outdg[i] == 0)zeroout++; } ans = zeroin > zeroout ? zeroin : zeroout; } int main() { while( scanf( "%d", &n) != EOF) { memset( first, -1, sizeof first); for( int i = 1; i <= n; i ++) { int a; while( true) { scanf( "%d", &a); if( a == 0) break; addedge( i, a); } } tarjan(n); printf( "%d\n", ans); } return 0; }
浙公网安备 33010602011771号