考研路茫茫——空调教室 HDU - 2242

众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们。Lele也是其中一个。而某教室旁边又摆着两个未装上的空调,更是引起人们无限YY。

一个炎热的下午,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 }

 

posted @ 2017-11-25 00:11  天之道,利而不害  阅读(227)  评论(0)    收藏  举报