upcoj2129

题意,给出一个五环图,求出切割某条边后使两个子树差值最小的最小差值。

这是一次和山东其他学校的练习赛中的一道题,当时想了很久各种超时,其实明明自己算了复杂度会超时但还无脑的去敲。。。太逗了。

想了各种优化,但其实还是自己主要思路没想好和复杂度控制的问题。

最后问了肖太爷的思路,参考了他的代码,原本自己思路也是往这边想的。。。就是过不来。

主要思路是边与边之间的联系,和p[x]的动态取值。。

从1点开始找  遍历边,同时控制点取值方法即可了。。

这是参考肖太爷代码后自己敲的:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int a[10010];
int vis[10010];
int ans;int k;
int h[10010];
int p[10010];
struct Edge{
    int y;
    int next;
}edge[10010*2];
void add(int x,int y)
{
    edge[k].y=y;
    edge[k].next=h[x];
    h[x]=k++;
}
void dfs(int x,int r)
{
    int v;
    p[x]=a[x];
    for(int i=h[x];i!=-1;i=edge[i].next)
    {
        v=edge[i].y;
        if(v==r)continue;		//判断回流
        dfs(v,x);			//继续找边
        p[x]+=p[v];
    }
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        sum=0;
        memset(p,0,sizeof(p));
        memset(h,-1,sizeof(h));
        k=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        for(int i=1;i<=n-1;i++)
        {
            int u,v;
            cin>>u>>v;
            add(u,v);
            add(v,u);
        }
        dfs(1,0);
        int ans=p[1];
        for (int i=1;i<=n;i++)
        {
            ans=min(ans,abs(p[1]-2*p[i]));
        }
        cout<<ans<<endl;
    }
}


 

原文地址:https://www.cnblogs.com/amourjun/p/5134159.html