题意,给出一个五环图,求出切割某条边后使两个子树差值最小的最小差值。
这是一次和山东其他学校的练习赛中的一道题,当时想了很久各种超时,其实明明自己算了复杂度会超时但还无脑的去敲。。。太逗了。
想了各种优化,但其实还是自己主要思路没想好和复杂度控制的问题。
最后问了肖太爷的思路,参考了他的代码,原本自己思路也是往这边想的。。。就是过不来。
主要思路是边与边之间的联系,和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; } }