您的位置:首页 > 其它

HDOJ树形DP专题之考研路茫茫——空调教室

2012-05-02 14:59 344 查看
题目链接

题目大意:给定一个连通无向图,每个结点有一个值,现要断开图中某条边,使得原图变成两个连通子图,且要使两个子图的值的差最小。输出最小差,若无法完成,则输出"impossible”

分析:要使断开某条边后,原图变成两个连通支,则断开的边一定是桥。对图进行DFS时,得到一颗树,图中有的而树中没有的边叫回边,回边一定不是桥。由此想到可用dfs将图转化为树来做,但树中的边不一定是原图中的桥,问题关键在于桥的判断。此题还需要注意的是可能有重边。

View Code

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <vector>
#define N 10001
#define M 40001
#define INF 0x7fffffff
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
using namespace std;
vector<int> dep
;
int u[M],v[M],cnt[M],next[M],first
,n,m;
int num
,sum
;
int p
,d
,dfn
,low
,dmax,id;
char vis
;
void dfs(int a,int fa)
{
int e,b;
d[a]=(fa==-1?0:d[fa]+1);
dmax=MAX(dmax,d[a]);
dep[d[a]].push_back(a);
for(e=first[a];e>=0;e=next[e])
{
b=v[e];
if(b==fa) continue;
if(vis[b])  low[a]=MIN(low[a],dfn[b]);
else
{
vis[b]=1;
dfn[b]=low[b]=++id;
dfs(b,p[b]=a);
low[a]=MIN(low[a],low[b]);
}
}
}
void dp()
{
int e,b,i,j;
memset(sum,0,sizeof(sum));
for(i=dmax;i>=0;i--)
{
for(j=0;j<dep[i].size();j++)
{
b=dep[i][j];
sum[b]+=num[b];
if(i) sum[p[b]]+=sum[b];
}
}
}
void addEdge(int a,int b,int e)
{
u[e]=a,v[e]=b;
cnt[e]=1;
next[e]=first[a];
first[a]=e;
}
int findEdge(int a,int b)
{
int e;
for(e=first[a];e>=0;e=next[e])
{
if(v[e]==b)
{
cnt[e]++;
return 1;
}
}
return 0;
}
int main()
{
int i,e,a,b,ans;
while(~scanf("%d%d",&n,&m))
{
for(i=0;i<n;i++)  scanf("%d",&num[i]);
memset(u,-1,sizeof(u));
memset(v,-1,sizeof(v));
memset(first,-1,sizeof(first));
memset(next,-1,sizeof(next));
memset(cnt,0,sizeof(cnt));
for(e=0;e<m;e++)
{
scanf("%d%d",&a,&b);
if(findEdge(a,b)+findEdge(b,a)==0)
{
addEdge(a,b,2*e);
addEdge(b,a,2*e+1);
}
}
memset(vis,0,sizeof(vis));
vis[0]=1;
dfn[0]=low[0]=id=1;
p[0]=-1;
dmax=0;
for(i=0;i<n;i++)  dep[i].clear();
dfs(0,-1);
dp();
ans=INF;
for(e=0;e<m;e++)
{
if(cnt[2*e]>1)  continue;
a=u[2*e],b=v[2*e];
if(p[a]==b&&low[a]>dfn[b]) ans=MIN(ans,abs(2*sum[a]-sum[0]));
else if(p[b]==a&&low[b]>dfn[a])  ans=MIN(ans,abs(2*sum[b]-sum[0]));
}
if(ans==INF)  puts("impossible");
else  printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: