http://acm.hdu.edu.cn/showproblem.php?pid=2242
很好的题目
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define inf (1<<30)
#define nMAX 10005
#define mMAX 20010
using namespace std;
int dfn[nMAX],low[nMAX],belon[nMAX],sta[nMAX],top,times,atype;
int s_edge,s_edge2,head[nMAX],head2[nMAX];
int n,num1[nMAX],num2[nMAX],SUM,ans;
struct Edge
{
int v,nxt;
}edge[2*mMAX],edge2[2*mMAX];
void addedge(int u,int v)
{
s_edge++;
edge[s_edge].v=v;
edge[s_edge].nxt=head[u];
head[u]=s_edge;
}
void addedge2(int u,int v)
{
s_edge2++;
edge2[s_edge2].v=v;
edge2[s_edge2].nxt=head2[u];
head2[u]=s_edge2;
}
void tarjan(int u,int fa)
{
int fg=0;
dfn[u]=low[u]=++times;
sta[++top]=u;
for(int e=head[u];e;e=edge[e].nxt)
{
int v=edge[e].v;
if(!fg&&v==fa) {fg=1;continue;}
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else low[u]=min(low[u],dfn[v]);
}
int j;
if(dfn[u]==low[u])
{
atype++;
do{
j=sta[top--];
belon[j]=atype;
num2[atype]+=num1[j];
}while(j!=u);
}
}
int dfs(int u,int pre)
{
int sum=num2[u];
for(int e=head2[u];e;e=edge2[e].nxt)
{
int v=edge2[e].v;
if(v==pre) continue;
sum+=dfs(v,u);
}
int t=abs(SUM-2*sum);
ans=min(ans,t);
return sum;
}
void init()
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(num2,0,sizeof(num2));
top=0;
times=0;
atype=0;
}
int main()
{
int i,j,m;
while(~scanf("%d%d",&n,&m))
{
SUM=0;
for(i=0;i<n;i++) {scanf("%d",&num1[i]);SUM+=num1[i];}
memset(head,0,sizeof(head));
s_edge=0;
while(m--)
{
scanf("%d%d",&i,&j);
addedge(i,j);
addedge(j,i);
}
init();
tarjan(0,-1);
if(atype==1){printf("impossible\n");continue;}
memset(head2,0,sizeof(head2));
s_edge2=0;
for(i=0;i<n;i++)
{
for(int e=head[i];e;e=edge[e].nxt)
{
int v=edge[e].v;
if(belon[i]!=belon[v]) addedge2(belon[i],belon[v]);
}
}
ans=inf;
dfs(1,0);
printf("%d\n",ans);
}
return 0;
}