1 /**********************************************************
  2 题目:    考研路茫茫——空调教室(hdu 2242)
  3 链接:    http://acm.hdu.edu.cn/showproblem.php?pid=2242
  4 算法:    双联通
  5 思路:    找到桥,然后计算桥两边的差,在把桥一边
  6          的值压缩到和另一边相邻的数上。
  7 
  8 ***********************************************************/
  9 
 10 #include<cstdio>
 11 #include<iostream>
 12 #include<cstring>
 13 #include<algorithm>
 14 #include<vector>
 15 #include<stack>
 16 using namespace std;
 17 
 18 const int mx=100005;
 19 int a[mx];
 20 stack<int>s;
 21 vector<int>g[mx];
 22 int flag,dfs_cut;
 23 int dfn[mx],low[mx],vs[mx];
 24 int ans,sum;
 25 
 26 void Init(int n)
 27 {
 28     int i;
 29     sum=0;
 30     for (i=0;i<n;i++)
 31     {
 32         g[i].clear();
 33         scanf("%d",&a[i]);
 34         sum+=a[i];
 35     }
 36     memset(dfn,0,sizeof(dfn));
 37     memset(low,0,sizeof(low));
 38     memset(vs,0,sizeof(vs));
 39     flag=dfs_cut=0;
 40     ans=sum;
 41 }
 42 
 43 void dfs(int u,int fa)
 44 {
 45     dfn[u]=low[u]=++dfs_cut;
 46     vs[u]=1;
 47     s.push(u);
 48     int p=1;      ///去重
 49     for (int i=0;i<g[u].size();i++)
 50     {
 51 
 52         int v=g[u][i];
 53         if (v==fa&&p)
 54         {
 55             p=0;
 56             continue;
 57         }
 58         if (!vs[v])
 59         {
 60             dfs(v,u);
 61             low[u]=min(low[u],low[v]);
 62             if (low[v]>dfn[u])    ///判断桥
 63             {
 64                 flag=1;
 65                 int temp=0,x;
 66                 
 67                 ///给桥一遍压缩
 68                 while (1)
 69                 {
 70                     x=s.top();
 71                     s.pop();
 72                     temp+=a[x];
 73                     if (x==v) break;
 74                 }
 75                 ans=min(ans,abs(sum-2*temp));
 76                 a[u]+=temp;
 77             }
 78 
 79         }
 80         else low[u]=min(low[u],dfn[v]);
 81     }
 82 }
 83 
 84 int main()
 85 {
 86     int n,m;
 87     while (~scanf("%d%d",&n,&m))
 88     {
 89         Init(n);
 90         while (m--)
 91         {
 92             int u,v;
 93             scanf("%d%d",&u,&v);
 94             g[u].push_back(v);
 95             g[v].push_back(u);
 96         }
 97         dfs(0,-1);
 98         if (flag) printf("%d\n",ans);
 99         else printf("impossible\n");
100     }
101 }

 

posted on 2016-05-06 20:46  pb2016  阅读(343)  评论(0编辑  收藏  举报