一看到这道题觉得很水,打了递归树形DP后RE了一组,后来发现必须非递归(BFS)
递归版本84分:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int N,point[1000003],next[2000003],v[2000003],c[2000003],cnt=0,f[1000003]; bool p[1000003]; long long sum=0; void insect(int x,int y,int z){next[cnt]=point[x];point[x]=cnt;v[cnt]=y;c[cnt]=z;cnt++;} void dfs(int x) { int i; f[x]=1; for (i=point[x];i!=-1;i=next[i]) if (p[v[i]]==0) { p[v[i]]=1; dfs(v[i]); f[x]+=f[v[i]]; sum+=(1LL*c[i]*abs(2*f[v[i]]-N)); } } int main() { int i,x,y,z; memset(point,-1,sizeof(point)); memset(next,-1,sizeof(next)); memset(v,0,sizeof(v)); memset(p,0,sizeof(p)); memset(c,0,sizeof(c)); memset(f,0,sizeof(0)); scanf("%d\n",&N); for (i=1;i<N;++i) { scanf("%d %d %d\n",&x,&y,&z); insect(x,y,z); insect(y,x,z); }p[1]=1;dfs(1); printf("%lld\n",sum); return 0; }
BFS版本AC:
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int N,point[1000003],next[2000003],v[2000003],c[2000003],cnt=0,f[1000003],s[1000003],fa[1000003]; int table[1000003],num=0,du[1000003]; bool p[1000003]; long long sum=0; void insect(int x,int y,int z){next[cnt]=point[x];point[x]=cnt;v[cnt]=y;c[cnt]=z;cnt++;} void dfs(int x) { int now,i,tmp=0; queue<int>q; for (i=1;i<=N;++i) { if (du[i]==1) q.push(i),f[i]=1; f[i]=1; } while (!q.empty()) { now=q.front(); q.pop(); p[now]=1; tmp=now; for (i=point[now];i!=-1;i=next[i]) if (p[v[i]]==0) { f[v[i]]+=f[now]; du[v[i]]--; if (du[v[i]]==1) q.push(v[i]); } } memset(p,0,sizeof(p)); p[tmp]=1; q.push(tmp); while (!q.empty()) { now=q.front(); q.pop(); for (i=point[now];i!=-1;i=next[i]) if (p[v[i]]==0) { p[v[i]]=1; sum+=(1LL*c[i]*abs(2*f[v[i]]-N)); q.push(v[i]); } } printf("%lld\n",sum); } int main() { int i,x,y,z; memset(point,-1,sizeof(point)); memset(next,-1,sizeof(next)); memset(du,0,sizeof(du)); memset(v,0,sizeof(v)); memset(p,0,sizeof(p)); memset(c,0,sizeof(c)); memset(f,0,sizeof(0)); scanf("%d\n",&N); for (i=1;i<N;++i) { scanf("%d %d %d\n",&x,&y,&z); du[x]++; du[y]++; insect(x,y,z); insect(y,x,z); }dfs(1); return 0; }