日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 1904 【强连通分量】.cpp

發布時間:2023/12/9 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。