POJ 1904 【强连通分量】.cpp
題意:
很久很久以前..
有一個國王..
他有好幾個兒子..
這些王子都喜歡上了鄰國的公主..
他們準備迎娶自己喜歡的公主中的一個..
國王就讓宰相給列一個清單..
宰相就給了國王一個清單..上面寫明了哪個王子將迎娶哪個鄰國的公主..
但是調皮的國王不太滿意~~
他還想知道他的兒子分別可以迎娶哪幾個公主中的一個而不會讓他的兄弟因此而吃醋..
所以宰相又得重新寫清單了..
?
噢..對了~鄰國的公主和王子人數一樣多~<這是一個奇怪的國家..>
輸入:
一個n表示有n個王子..
接下來n行每行有一個m表示第i個王子喜歡m個公主..
然后給出m個公主的序號..
最后一行有n個數..代表第i個王子最后迎娶了的公主..
?
輸出:
n行..每行第一個是m 表示有m個公主他可以選擇~
然后m個數是公主的序號..
P.S 麻煩的國王還要求公主序號按從小到大給出..
<這是一些花心的王子..= =!! 可恨..>
?
思路:
求強連通分量..
王子和喜歡的公主連邊..
最后娶了的公主和該王子之間也連邊..
然后每個強連通分量就是他可以選擇的公主序號..
?
Tips:
因為類似拆點了..所以數組要開大一點..
?
Code:
View Code 1 #include <stdio.h> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int INF = 0x1f1f1f1f; 6 #define clr(x) memset(x, 0, sizeof(x)) 7 const int MAXN = 2010*3; 8 9 struct Edge 10 { 11 int to; 12 int next; 13 }edge[10000010]; 14 int head[MAXN]; 15 int tot; 16 17 void add(int s, int u) 18 { 19 edge[tot].to = u; 20 edge[tot].next = head[s]; 21 head[s] = tot++; 22 } 23 24 int dfn[MAXN], low[MAXN]; 25 int ins[MAXN], sta[MAXN], col[MAXN]; 26 int ti, top, cnt; 27 int n; 28 29 void tarjan(int u) 30 { 31 int i, k; 32 dfn[u] = low[u] = ++ti; 33 ins[u] = 1; 34 sta[++top] = u; 35 for(i = head[u]; i != -1; i = edge[i].next) { 36 k = edge[i].to; 37 if(dfn[k] == 0) { 38 tarjan(k); 39 low[u] = min(low[u], low[k]); 40 } else if(ins[k]) { 41 low[u] = min(low[u], dfn[k]); 42 } 43 } 44 if(dfn[u] == low[u]) { 45 cnt++; 46 do 47 { 48 k = sta[top--]; 49 col[k] = cnt; 50 ins[k] = 0; 51 }while(u != k); 52 } 53 54 } 55 56 void solve() 57 { 58 int i, k; 59 ti = top = cnt = 0; 60 clr(dfn); 61 for(i = 1; i <= n; ++i) 62 if(!dfn[i]) 63 tarjan(i); 64 } 65 66 int main() 67 { 68 int i, j, k; 69 int a, m; 70 int mar; 71 int ans[MAXN]; 72 while(scanf("%d", &n) != EOF) 73 { 74 tot = 0; 75 memset(head, 0xff, sizeof(head)); 76 77 for(i = 1; i <= n; ++i) { 78 scanf("%d", &m); 79 while(m--) { 80 scanf("%d", &a); 81 add(i, a+n); 82 } 83 } 84 for(i = 1; i <= n; ++i) { 85 scanf("%d", &mar); 86 add(mar+n, i); 87 } 88 89 solve(); 90 91 int tmp; 92 for(i = 1; i <= n; ++i) { 93 tmp = 0; 94 for(j = head[i]; j != -1; j = edge[j].next) { 95 k = edge[j].to; 96 if(col[i] == col[k]) 97 ans[tmp++] = k; 98 } 99 sort(ans, ans+tmp); 100 printf("%d", tmp); 101 for(j = 0; j < tmp; ++j) 102 printf(" %d", ans[j]-n); 103 puts(""); 104 } 105 } 106 return 0; 107 }?
?
題目鏈接:http://poj.org/problem?id=1904
轉載于:https://www.cnblogs.com/Griselda/archive/2012/10/05/2711974.html
總結
以上是生活随笔為你收集整理的POJ 1904 【强连通分量】.cpp的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UrlRewrite(Url重写技术)
- 下一篇: 【转贴】mysql导入数据load da