Initiate

Call A Spade a Spade
posts - 14, comments - 3, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

poj 3140 Contestants Division

Posted on 2010-01-24 00:02 Initiate 阅读(173) 评论(0)  编辑 收藏 引用

题目:把一个带权值的树断开一条连线使其变为两个树,且这两部分的权值和之差最小。
算法:用向量组做邻接表存储数据,用dfs将树扫描一遍,从最底部开始判断。

#include<iostream>
#include<vector>
using namespace std;
int n,m,cas;
vector<int>vec[100010];
int per[100010],vis[100010];
long long cnt[100010];
long long total,res;
long long dfs(int t)
{
vis[t]=1;
cnt[t]=per[t];
for(int i=0 ;i<vec[t].size();i++)
{
   int a=vec[t][i];
   if(vis[a])continue;
   cnt[a] = dfs(a);
   cnt[t] +=cnt[a];
   long long temp;
   if(total-cnt[a]>=cnt[a])
    temp=total - 2*cnt[a];
   else
    temp=2*cnt[a]-total;
   if( temp < res ) res=temp;
   }
return cnt[t];
}
int main()
{
int i,j,p,q;
while (scanf("%d%d", &n, &m),n || m)
{
   total=0;
   res=1000000000000000LL;
   for(i=1;i<=n;i++)
   {
    scanf("%d", &per[i]);
    total +=per[i];
    vec[i].clear();
    cnt[i]=0;
    vis[i]=0;
   }
   for(i=1;i<=m;i++)
   {
    scanf("%d%d",&p,&q);
    vec[p].push_back(q);
    vec[q].push_back(p);
   }
   dfs(1);
   printf("Case %d: %lld\n", ++cas, res);
   }
return 0;
}

阅读全文
类别:Poj 查看评论

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理