Regional_2011_H Holiday's Accommodation

来源:互联网 发布:mac如何修改磁盘名称 编辑:程序博客网 时间:2024/05/23 19:17

题目地址: 1 LA 戳这里   2 hdu 2011_Chengdu_H


题目大意:  给你一颗树 ,告诉你每条边的权值,现在每个节点上的人要到其他的地方去,问所有里程加起来最多可以是多少?


先估计一下上界:

对于每一条边: 它作为割边将图分为两部分,假设这两边的人都尽可能的夸过这条边,这样在这条边上的贡献将达到最大。

先转化为有根树后,取2*min(k,n-k)  k是孩子节点的树的size


案例是可以过的,直接敲了 ac 应该是正确的算法 正确性有待证明

LA上直接dfs就可以了

如果是杭电会爆栈  用c++交 + 手动改栈的大小 #proma comment(linker,“/stack1024000000,1024000000”)


代码:

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<cstdio>#include<vector>#include<cstring>using namespace std;struct edge{    int u;    int v;    int w;};int min(int a,int b){    return a<b?a:b;}edge e[1000005];vector<int>  G[1000005];// bool vis[1000005];int p[1000005];     //    记录父亲节点int tree_size[1000005];int n;void dfs(int u,int fa){    tree_size[u]++;    int d=G[u].size();        for(int i=0;i<d;i++)    {        int v=G[u][i];        if(v!=fa)        {            dfs(v,p[v]=u);            tree_size[u]+=tree_size[v];        }                    }            }void  init(){    for(int i=0;i<1000005;i++)        G[i].clear();        memset(p,0,sizeof(p));    memset(tree_size,0,sizeof(tree_size));    }int main(){        int cas;    cin>>cas;            for(int l=0;l<cas;l++)    {                init();                cin>>n;                int a,b,c;                for(int i=0;i<n-1;i++)        {            scanf("%d%d%d",&a,&b,&c);            G[a-1].push_back(b-1);            G[b-1].push_back(a-1);                        e[i].u=a-1;            e[i].v=b-1;            e[i].w=c;                    }        p[0]=-1;        dfs(0,-1);                                        long long ans=0;                for(int i=0;i<n-1;i++)        {            int aa=e[i].u;            int bb=e[i].v;                        if(p[aa]==bb)            {                ans+=2*min(tree_size[aa],n-tree_size[aa])*e[i].w;            }                        else            {                                ans+=2*min(tree_size[bb],n-tree_size[bb])*e[i].w;            }        }                cout<<"Case #"<<l+1<<": "<<ans<<endl;            }}

关于上界可达正确性的证明 想清楚了子补上来吧

0 0