标签:strong for type rom ext rup panel printf from
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3232 Accepted Submission(s): 1283
题意:
有n个点,n-1条边的树,边有权值,有k个坏点,要求去掉一些边让所有的坏点不相互联通,问去掉的最小边权值。
代码:
//两个相邻的点都是坏点时必须去掉他们之间的边,儿子是坏点父亲不是坏点时 //可以至少保留1个儿子坏点去掉其他的兄弟坏点的边,我们必然会保留边权值大的 //那个儿子,然后向他的祖先传递坏点信息并更新dp(隔离那个坏点的最小边权)。 #include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int inf=0x7fffffff; int t,n,k,dp[100009],f[100009],ma[100009],head[100009],tol; ll ans; struct node{ int v,w,next; }nodes[200009]; void Add(int x,int y,int z){ nodes[tol].v=y; nodes[tol].w=z; nodes[tol].next=head[x]; head[x]=tol++; } void dfs(int u,int fa){ dp[u]=inf; ma[u]=f[u]; ll tmp=0; for(int i=head[u];i!=-1;i=nodes[i].next){ int v=nodes[i].v; if(v==fa) continue; dfs(v,u); if(!ma[v]) continue; if(f[u]) ans+=min(nodes[i].w,dp[v]); else{ ans+=min(tmp,1LL*min(dp[v],nodes[i].w)); tmp=max(tmp,1LL*min(dp[v],nodes[i].w)); } } if(tmp!=0){ dp[u]=tmp; ma[u]=1; } } int main() { scanf("%d",&t); while(t--){ tol=0; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&k); int x,y,z; for(int i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); Add(x,y,z); Add(y,x,z); } memset(f,0,sizeof(f)); for(int i=0;i<k;i++){ scanf("%d",&x); f[x]=1; } memset(ma,0,sizeof(ma)); ans=0; dfs(0,-1); printf("%I64d\n",ans); } return 0; }
标签:strong for type rom ext rup panel printf from
原文地址:http://www.cnblogs.com/--ZHIYUAN/p/6721194.html