【DFS】 HDU 3298 Contestants

随便以一个点为根 计算其子树和自己本身的点值

然后枚举已切每个点的ans取最小值

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <time.h>;
#define cler(arr, val)    memset(arr, val, sizeof(arr))
#define IN     freopen ("in.txt" , "r" , stdin);
#define OUT  freopen ("out.txt" , "w" , stdout);
typedef long long  LL;
const int MAXN = 200010;//点数的最大值
const int MAXM = 200006;//边数的最大值
const int INF = 0x3f3f3f3f;
const int mod = 10000007;
LL point[MAXN],num[MAXN];
vector<int>edge[MAXN];
bool vis[MAXN];
LL abs1(LL a)
{
    if(a>0) return a;
    else return -a;
}
void dfs(int u)
{
    vis[u]=true;
    for(int i=0;i<edge[u].size();i++)
    {
        int v=edge[u][i];
        if(!vis[v])
        {
            dfs(v);
            point[u]+=point[v];
        }
    }
}
int main()
{
    int m,n,cas=0;
   // IN;
    while(scanf("%d%d",&n,&m),m+n)
    {
        LL sum=0;
        cler(point,0);
        cler(num,0);
        for(int i=1;i<=n;i++)
        {
            edge[i].clear();
            scanf("%I64d",&point[i]);
            sum+=point[i];
        }
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            edge[a].push_back(b);
            edge[b].push_back(a);
        }
        LL ans=9999999999999;
        cler(vis,false);
        dfs(1);
        for(int i=1;i<=n;i++)
            ans=min(ans,abs1(sum-2*point[i]));
        printf("Case %d: %I64d\n",++cas,ans);
    }
}


posted @ 2014-09-26 22:05  kewowlo  阅读(148)  评论(0编辑  收藏  举报