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;
}
}

浙公网安备 33010602011771号