您的位置:首页 > 其它

poj_3140 Contestants Division(树形dp)

2017-02-04 16:32 477 查看
ContestantsDivision

TimeLimit:2000MS MemoryLimit:65536K
TotalSubmissions:9870 Accepted:2807
Description

InthenewACM-ICPCRegionalContest,aspecialmonitoringandsubmittingsystemwillbesetup,andstudentswillbeabletocompeteattheirownuniversities.Howeverthere’soneproblem.Duetothehighcostofthenewjudgingsystem,theorganizingcommittee
canonlyaffordtosetthesystemupsuchthattherewillbeonlyonewaytotransferinformationfromoneuniversitytoanotherwithoutpassingthesameuniversitytwice.Thecontestantswillbedividedintotwoconnectedregions,andthedifferencebetween
thetotalnumbersofstudentsfromtworegionsshouldbeminimized.Canyouhelpthejuriestofindtheminimumdifference?

Input

Therearemultipletestcasesintheinputfile.EachtestcasestartswithtwointegersNand
M,(1≤N≤100000,1≤M≤1000000),thenumberofuniversitiesandthenumberofdirectcommunicationlinesetupbythecommittee,respectively.Universitiesarenumberedfrom1toN.Thenextlinehas
Nintegers,theKthintegerisequaltothenumberofstudentsinuniversitynumberedK.Thenumberofstudentsinanyuniversitydoesnotexceed100000000.EachofthefollowingMlineshastwointegers
s,t,anddescribesacommunicationlineconnectinguniversitysanduniversity
t.Allcommunicationlinesofthisnewsystemarebidirectional.

N=0,M=0indicatestheendofinputandshouldnotbeprocessedbyyourprogram.

Output

Foreverytestcase,outputoneinteger,theminimumabsolutedifferenceofstudentsbetweentworegionsintheformatasindicatedinthesampleoutput.

SampleInput
76
1111111
12
27
37
46
62
57
00

SampleOutput
Case1:1


比较暴力的树形dp做法:

设sum[u]为以u为根结点的树中结点值总和。

设dp[u]为在u为根结点的树中将整颗树分成两棵子树,使两子树的sum的差最小的方案,值为子树之差。

整颗树以边u->v分成两子树的sum的差即树总和-sum[v]-sum[v]

则状态方程:dp[u]=min(dp[u],dp[v],树总和-2*sum[v])

-----------------------------------

注意答案可能是大于int范围的数,所以dp[u]必须初始化为一个更大的数,可以直接初始化为树总和,

因为答案显然不会大于树总和。


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<stack>
#include<bitset>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<algorithm>
#defineFOPfreopen("data.txt","r",stdin)
#defineFOP2freopen("data1.txt","w",stdout)
#defineinf0x3f3f3f3f
#definemaxn100010
#definemod1000000007
#definePIacos(-1.0)
#defineLLlonglong
usingnamespacestd;

LLAbs(LLa)
{
returna<0?-a:a;
}

intn,m;
LLval[maxn],sum[maxn],dp[maxn];
vector<int>G[maxn];

voiddfs(intu,intfa)
{
dp[u]=sum[0];
for(inti=0;i<G[u].size();i++)
{
intv=G[u][i];

if(v==fa)continue;
dfs(v,u);

sum[u]+=sum[v];

dp[u]=min(dp[u],Abs(sum[0]-2*sum[v]));
dp[u]=min(dp[u],dp[v]);
}
}

intmain()
{
intcasen=0;
while(~scanf("%d%d",&n,&m)&&n)
{
memset(sum,0,sizeof(sum));
for(inti=1;i<=n;i++)G[i].clear();

for(inti=1;i<=n;i++)
{
scanf("%lld",&val[i]);
sum[i]=val[i];
sum[0]+=val[i];
}

inta,b;
for(inti=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
}

dfs(1,0);

printf("Case%d:",++casen);
printf("%lld\n",dp[1]);
}
return0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: