http://acm.hdu.edu.cn/showproblem.php?pid=4313
贪心算法:类似kruskal最小生成树的过程,不过此处将边按权值从大到小排列,每次将边加进来时要判断是否会使两个危险的点连通,是的话这条边就是需要被删除的,否则将它加到树上。
还有一种 说是树形DP 不懂
这题一直WA 看了秦老师的代码 用的--int64 就改了下数据类型 过了。。。
并查集+快排+去掉危险的结点
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 typedef struct node 5 { 6 int v1,v2,e; 7 }st; 8 int father[100001],w,f[100001]; 9 st q[100001]; 10 int cmp(const void *a,const void *b) 11 { 12 return ((st *)b)->e-((st *)a)->e; 13 } 14 int find(int x) 15 { 16 if(x!=father[x]) 17 father[x] = find(father[x]); 18 return father[x]; 19 } 20 void union1(int x,int y,int z) 21 { 22 father[x] = y; 23 } 24 int main() 25 { 26 int i,j,k,n,m,t,flag; 27 __int64 s; 28 scanf("%d", &t); 29 while(t--) 30 { 31 memset(f,0,sizeof(f)); 32 scanf("%d%d", &n,&k); 33 s = 0; 34 for(i = 0; i < n ; i++) 35 father[i] = i; 36 for(i = 0; i < n-1 ; i++) 37 scanf("%d%d%d", &q[i].v1,&q[i].v2,&q[i].e); 38 qsort(q,n-1,sizeof(q[0]),cmp); 39 for(i = 0 ; i < k ;i++) 40 { 41 scanf("%d",&w); 42 f[w] = 1; 43 } 44 for(i = 0 ;i < n-1 ; i++) 45 { 46 int px = find(q[i].v1); 47 int py = find(q[i].v2); 48 if(px!=py) 49 { 50 if(f[px]!=1||f[py]!=1) 51 { 52 union1(px,py,q[i].e); 53 if(f[px]==1) 54 f[py] = 1; 55 } 56 else 57 s+=q[i].e; 58 } 59 } 60 printf("%I64d\n",s); 61 } 62 return 0; 63 }