-
Accumulation Degree
- POJ - 3585
- 题意:
- 题意:找一个点使得,使得从这个点出发作为源点,发出的流量最大,输出这个最大的流量。
- 思路:把点1提为树根,从1出发 进行最大流量记录,在这个过程中把 边流量可以推到流向的点。
- 在进行换根dp, 转移方程为 :
-
if(in[fa[u]]==1)g[u]+=flow[u]; else g[u]+=min(flow[u],g[fa[u]]-min(flow[u],f[u]));
- 得到的g数组就是以每个点为根的最大流量,最终取一个最值即可。
-
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define inf 0x3f3f3f3f #define maxn 999999 struct node { int v,to,w; } edge[maxn]; int head[maxn],id,fa[maxn],cnt; int t,n,x,y,z,ans,flow[maxn]; int in[maxn],f[maxn],g[maxn]; void add(int u,int v,int w) { edge[++cnt].v=v; edge[cnt].to=head[u]; edge[cnt].w=w; head[u]=cnt; in[u]++; } void dfs(int u,int p) { f[u]=0; if(in[u]==1&&u!=1)return ; for(int i=head[u]; i!=-1; i=edge[i].to) { int v=edge[i].v; if(v==p)continue; flow[v]=edge[i].w; fa[v]=u; dfs(v,u); if(in[v]==1)f[u]+=edge[i].w; else f[u]+=min(edge[i].w,f[v]); } } void dp(int u) { g[u]=f[u]; if(u!=1) { if(in[fa[u]]==1)g[u]+=flow[u]; else g[u]+=min(flow[u],g[fa[u]]-min(flow[u],f[u])); } for(int i=head[u]; i!=-1; i=edge[i].to) { int v=edge[i].v; if(v==fa[u])continue; dp(v); } } int main() { scanf("%d",&t); while(t--) { ans=cnt=0; memset(head,-1,sizeof(head)); memset(f,0,sizeof(f)); memset(flow,0,sizeof(flow)); memset(g,0,sizeof(g)); memset(in,0,sizeof(in)); scanf("%d",&n); for(int i=1; i<n; i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } dfs(1,0); dp(1); for(int i=1; i<=n; i++) ans=max(ans,g[i]); printf("%d\n",ans); } return 0; }
Accumulation Degree POJ - 3585 -树形DP
最新推荐文章于 2022-02-03 20:32:43 发布