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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HDU 2242 双连通分量 考研路茫茫——空调教室

發(fā)布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 2242 双连通分量 考研路茫茫——空调教室 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

思路就是求邊雙連通分量,然后縮點,再用樹形DP搞一下。

代碼和求強連通很類似,有點神奇,=_=,慢慢消化吧

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <stack> 6 using namespace std; 7 8 const int maxn = 10000 + 10; 9 const int maxm = 20000 + 10; 10 11 int n, m; 12 int a[maxn]; 13 14 struct Edge 15 { 16 int v, nxt; 17 }edges[maxm * 2]; 18 int ecnt; 19 int head[maxn]; 20 21 bool vis[maxn]; 22 23 void AddEdge(int u, int v) 24 { 25 edges[ecnt].v = v; 26 edges[ecnt].nxt = head[u]; 27 head[u] = ecnt++; 28 } 29 30 stack<int> S; 31 int dfs_clock, scc_cnt; 32 int low[maxn], pre[maxn], sccno[maxn], w[maxn]; 33 34 void dfs(int u, int fa) 35 { 36 low[u] = pre[u] = ++dfs_clock; 37 S.push(u); 38 39 for(int i = head[u]; ~i; i = edges[i].nxt) 40 { 41 if(i == (fa ^ 1)) continue; 42 int v = edges[i].v; 43 if(!pre[v]) 44 { 45 dfs(v, i); 46 low[u] = min(low[u], low[v]); 47 } 48 else if(!sccno[v]) low[u] = min(low[u], pre[v]); 49 } 50 51 if(pre[u] == low[u]) 52 { 53 scc_cnt++; 54 for(;;) 55 { 56 int x = S.top(); S.pop(); 57 sccno[x] = scc_cnt; 58 w[scc_cnt] += a[x]; 59 if(x == u) break; 60 } 61 } 62 } 63 64 void find_scc() 65 { 66 scc_cnt = dfs_clock = 0; 67 memset(w, 0, sizeof(w)); 68 memset(pre, 0, sizeof(pre)); 69 memset(sccno, 0, sizeof(sccno)); 70 for(int i = 0; i < n; i++) if(!pre[i]) dfs(i, -1); 71 } 72 73 vector<int> G[maxn]; 74 75 void dfs2(int u) 76 { 77 vis[u] = true; 78 for(int i = 0; i < G[u].size(); i++) 79 { 80 int v = G[u][i]; 81 if(vis[v]) continue; 82 dfs2(v); 83 w[u] += w[v]; 84 } 85 } 86 87 int main() 88 { 89 while(scanf("%d%d", &n, &m) == 2 && n) 90 { 91 int sum = 0; 92 for(int i = 0; i < n; i++) { scanf("%d", a + i); sum += a[i]; } 93 94 memset(head, -1, sizeof(head)); 95 ecnt = 0; 96 97 while(m--) 98 { 99 int u, v; scanf("%d%d", &u, &v); 100 AddEdge(u, v); AddEdge(v, u); 101 } 102 103 find_scc(); 104 105 if(scc_cnt == 1) { puts("impossible"); continue; } 106 107 for(int i = 1; i <= scc_cnt; i++) G[i].clear(); 108 for(int u = 0; u < n; u++) 109 for(int i = head[u]; ~i; i = edges[i].nxt) 110 { 111 int v = edges[i].v; 112 if(sccno[u] != sccno[v]) G[sccno[u]].push_back(sccno[v]); 113 } 114 115 memset(vis, false, sizeof(vis)); 116 dfs2(1); 117 118 int ans = 1000000000; 119 for(int i = 1; i <= scc_cnt; i++) ans = min(ans, abs(sum - w[i] * 2)); 120 printf("%d\n", ans); 121 } 122 123 return 0; 124 } 代碼君

?

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

總結(jié)

以上是生活随笔為你收集整理的HDU 2242 双连通分量 考研路茫茫——空调教室的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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