codehunter 「Adera 6」杯省選模擬賽 網絡升級 【樹形dp】
阿新 • • 發佈:2018-07-15
siri ren getchar 樹形 usr mes getc img pre
直接抄ppt好了……來自SiriusRen
註意只用對根判斷是否喲留下兒子
#include<iostream> #include<cstdio> using namespace std; const int N=100005; long long n,ans,h[N],cnt,fa[N],dis[N],d1,d2,l1,l2,c1,at[N],bt[N],a[N],b[N],tota,totb,nw,tmp,g[N]; bool del[N]; struct qwe { long long ne,to,va,c; }e[N<<1]; long long read() { long long r=0,f=1; char p=getchar(); while(p>‘9‘||p<‘0‘) { if(p==‘-‘) f=-1; p=getchar(); } while(p>=‘0‘&&p<=‘9‘) { r=r*10+p-48; p=getchar(); } return r*f; } void add(long long u,long long v,long long w,long long c) { cnt++; e[cnt].ne=h[u]; e[cnt].to=v; e[cnt].va=w; e[cnt].c=c; h[u]=cnt; } void dfs(long long u,long long fat) { fa[u]=fat; for(int i=h[u];i;i=e[i].ne) if(e[i].to!=fat) { dis[e[i].to]=dis[u]+e[i].va; dfs(e[i].to,u); } } void dfs1(long long u,long long fat) { fa[u]=fat; for(int i=h[u];i;i=e[i].ne) if(e[i].to!=fat) { dfs1(e[i].to,u); dis[u]=max(dis[u],dis[e[i].to]+e[i].va); } } long long dp(long long u,long long ti) { for(int i=h[u];i;i=e[i].ne) if(e[i].to!=fa[u]&&dis[e[i].to]+e[i].va==dis[u]) g[u]+=dp(e[i].to,e[i].c); if(!g[u]) return ti; return min(ti,g[u]); } int main() { n=read(); for(int i=1;i<n;i++) { long long x=read(),y=read(),z=read(),c=read(); add(x,y,z,c),add(y,x,z,c); } dfs(1,0); for(int i=1;i<=n;i++) if(dis[i]>dis[d1]) d1=i; fa[d1]=0,dis[d1]=0; dfs(d1,0); for(int i=1;i<=n;i++) if(dis[i]>dis[d2]) d2=i; for(int i=d2;i;i=fa[i]) if((dis[fa[i]]<<1)<dis[d2]&&(dis[i]<<1)>=dis[d2]) d1=i; l1=dis[d1],l2=dis[d2]-dis[d1]; for(int i=1;i<=n;i++) dis[i]=0; fa[d1]=0; dfs1(d1,0); for(int i=h[d1];i;i=e[i].ne) { if(dis[e[i].to]+e[i].va==l1) a[++tota]=e[i].to,at[tota]=e[i].c; else if(dis[e[i].to]+e[i].va==l2) b[++totb]=e[i].to,bt[totb]=e[i].c; } for(int i=1;i<=tota;i++) { nw=dp(a[i],at[i]); ans+=nw; if(nw>tmp) tmp=nw; } nw=0; for(int i=1;i<=n;i++) nw+=dp(b[i],bt[i]); if(l2&&nw<tmp) ans=ans-tmp+nw; printf("%lld\n",ans); return 0; }
codehunter 「Adera 6」杯省選模擬賽 網絡升級 【樹形dp】