考研路茫茫——空调教室 HDU - 2242
众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们。Lele也是其中一个。而某教室旁边又摆着两个未装上的空调,更是引起人们无限YY。
一个炎热的下午,Lele照例在教室睡觉的时候,竟然做起了空调教室的美梦。
Lele梦到学校某天终于大发慈悲给某个教室安上了一个空调。而且建造了了M条通气管道,让整个教学楼的全部教室都直接或间接和空调教室连通上,构成了教室群,于是,全部教室都能吹到空调了。
不仅仅这样,学校发现教室人数越来越多,单单一个空调已经不能满足大家的需求。于是,学校决定封闭掉一条通气管道,把全部教室分成两个连通的教室群,再在那个没有空调的教室群里添置一个空调。
当然,为了让效果更好,学校想让这两个教室群里的学生人数尽量平衡。于是学校找到了你,问你封闭哪条通气管道,使得两个教室群的人数尽量平衡,并且输出人数差值的绝对值。
一个炎热的下午,Lele照例在教室睡觉的时候,竟然做起了空调教室的美梦。
Lele梦到学校某天终于大发慈悲给某个教室安上了一个空调。而且建造了了M条通气管道,让整个教学楼的全部教室都直接或间接和空调教室连通上,构成了教室群,于是,全部教室都能吹到空调了。
不仅仅这样,学校发现教室人数越来越多,单单一个空调已经不能满足大家的需求。于是,学校决定封闭掉一条通气管道,把全部教室分成两个连通的教室群,再在那个没有空调的教室群里添置一个空调。
当然,为了让效果更好,学校想让这两个教室群里的学生人数尽量平衡。于是学校找到了你,问你封闭哪条通气管道,使得两个教室群的人数尽量平衡,并且输出人数差值的绝对值。
Input本题目包含多组数据,请处理到文件结束。
每组测试第一行包含两个整数N和M(0<N<=10000,0<M<20000)。其中N表示教室的数目(教室编号从0到N-1),M表示通气管道的数目。
第二行有N个整数Vi(0<=Vi<=1000),分别代表每个教室的人数。
接下来有M行,每行两个整数Ai,Bi(0<=Ai,Bi<N),表示教室Ai和教室Bi之间建了一个通气管道。
Output对于每组数据,请在一行里面输出所求的差值。
如果不管封闭哪条管道都不能把教室分成两个教室群,就输出"impossible"。
Sample Input
4 3 1 1 1 1 0 1 1 2 2 3 4 3 1 2 3 5 0 1 1 2 2 3
Sample Output
0 1
1 // A.cpp: 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include<stack> 6 #include<cmath> 7 #include<cstdio> 8 #include<vector> 9 #include<cstring> 10 #include<iostream> 11 #include<algorithm> 12 using namespace std; 13 14 const int INF = 0x3f3f3f3f; 15 const int maxm = 10005; 16 const int maxn = 20005; 17 18 int k,n,m,tot,ans,Sum,index; 19 int va[maxn],cmp[maxn],Low[maxn],Dfn[maxn],cnt[maxn],head[maxn]; 20 bool use[maxn]; 21 22 stack<int> S; 23 vector<int> G[maxn]; 24 25 struct node { 26 int to, next; 27 }e[2*maxm]; 28 29 void Inite() { 30 k = tot = index = 0; 31 memset(cmp, 0, sizeof(use)); 32 memset(cnt, 0, sizeof(cnt)); 33 memset(use, 0, sizeof(use)); 34 memset(head, -1, sizeof(head)); 35 } 36 37 void addedge(int u, int v) { 38 e[tot].to = v; 39 e[tot].next = head[u]; 40 head[u] = tot++; 41 } 42 43 void Tarjan(int u, int pa) { 44 Low[u] = Dfn[u] = index++; 45 use[u] = true; 46 S.push(u); 47 48 bool flag = false; 49 for (int i = 0;i < G[u].size();i++) { 50 int v = G[u][i]; 51 if (v == pa && !flag) { flag = true; continue; } 52 if (!use[v]) Tarjan(v, u); 53 Low[u] = min(Low[u], Low[v]); 54 } 55 int v; 56 if (Dfn[u] == Low[u]) { 57 k++; 58 do { 59 v = S.top(); 60 S.pop(); 61 cmp[v] = k; 62 cnt[k] = cnt[k] + va[v]; 63 } while (v != u); 64 } 65 } 66 67 int DFS(int u, int pa) { 68 int sum = cnt[u]; 69 for (int i = head[u];i != -1;i = e[i].next) { 70 int v = e[i].to; 71 if (v == pa) continue; 72 sum += DFS(v, u); 73 } 74 ans = min(ans, abs(Sum - 2 * sum)); 75 return sum; 76 } 77 78 void Solve() { 79 80 while (!S.empty()) S.pop(); 81 Tarjan(0, 0); 82 83 if (k == 1) { printf_s("impossible\n"); return; } 84 for (int u = 0;u < n;u++) { 85 for (int i = 0;i < G[u].size();i++) { 86 int v = G[u][i]; 87 if (cmp[u] == cmp[v]) continue; 88 addedge(cmp[u], cmp[v]); 89 } 90 } 91 92 ans = INF; 93 DFS(1, 0); 94 printf_s("%d\n", ans); 95 } 96 97 int main() 98 { 99 while (scanf_s("%d%d", &n, &m) != EOF) { 100 Inite(); 101 Sum = 0; 102 for (int i = 0;i < n;i++) { 103 scanf_s("%d", &va[i]); 104 Sum += va[i]; 105 G[i].clear(); 106 } 107 for (int i = 0;i < m;i++) { 108 int a, b; 109 scanf_s("%d%d", &a, &b); 110 G[a].push_back(b); 111 G[b].push_back(a); 112 } 113 Solve(); 114 } 115 return 0; 116 }

浙公网安备 33010602011771号