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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

loj 1210 (求最少的加边数使得图变成强连通)

發(fā)布時間:2024/10/12 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 loj 1210 (求最少的加边数使得图变成强连通) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接:http://lightoj.com/volume_showproblem.php?problem=1210

思路:首先是縮點染色,然后重建并且統(tǒng)計新圖中的每個點的入度和出度,于是答案就是max(入度為0的點的個數(shù), 出度為0的點的個數(shù),這里有一個trick就是如果scc_count == 1,那么應(yīng)該輸出0.

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <stack> 6 using namespace std; 7 8 const int MAXN = (20000 + 20); 9 int n, m, NE; 10 struct Edge { 11 int v, next; 12 } edge[MAXN << 2]; 13 14 int head[MAXN]; 15 void Insert(int u, int v) 16 { 17 edge[NE].v = v; 18 edge[NE].next = head[u]; 19 head[u] = NE++; 20 } 21 22 int cnt, scc_count; 23 int low[MAXN], dfn[MAXN], color[MAXN]; 24 bool mark[MAXN]; 25 stack<int >S; 26 27 void Tarjan(int u) 28 { 29 low[u] = dfn[u] = ++cnt; 30 mark[u] = true; 31 S.push(u); 32 for (int i = head[u]; i != -1; i = edge[i].next) { 33 int v = edge[i].v; 34 if (dfn[v] == 0) { 35 Tarjan(v); 36 low[u] = min(low[u], low[v]); 37 } else if (mark[v]) { 38 low[u] = min(low[u], dfn[v]); 39 } 40 } 41 if (low[u] == dfn[u]) { 42 scc_count++; 43 int v; 44 do { 45 v = S.top(); 46 S.pop(); 47 mark[v] = false; 48 color[v] = scc_count; 49 } while (u != v); 50 } 51 } 52 53 int Indegree[MAXN], Outdegree[MAXN]; 54 55 int main() 56 { 57 int _case, t = 1; 58 scanf("%d", &_case); 59 while (_case--) { 60 scanf("%d %d", &n, &m); 61 NE = 0; 62 memset(head, -1, sizeof(head)); 63 while (m--) { 64 int u, v; 65 scanf("%d %d", &u, &v); 66 Insert(u, v); 67 } 68 cnt = scc_count = 0; 69 memset(dfn, 0, sizeof(dfn)); 70 memset(mark, false, sizeof(mark)); 71 for (int i = 1; i <= n; i++) { 72 if (dfn[i] == 0) Tarjan(i); 73 } 74 memset(Indegree, 0, sizeof(Indegree)); 75 memset(Outdegree, 0, sizeof(Outdegree)); 76 for (int u = 1; u <= n; u++) { 77 for (int i = head[u]; i != -1; i = edge[i].next) { 78 int v = edge[i].v; 79 if (color[u] != color[v]) { 80 Indegree[color[v]]++; 81 Outdegree[color[u]]++; 82 } 83 } 84 } 85 int ans1 = 0, ans2 = 0; 86 for (int i = 1; i <= scc_count; i++) { 87 if (Indegree[i] == 0) ans1++; 88 if (Outdegree[i] == 0) ans2++; 89 } 90 printf("Case %d: ", t++); 91 if (scc_count == 1) { 92 puts("0"); 93 } else 94 printf("%d\n", max(ans1, ans2)); 95 } 96 return 0; 97 } 98 99 100 View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/wally/p/3529842.html

總結(jié)

以上是生活随笔為你收集整理的loj 1210 (求最少的加边数使得图变成强连通)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。