2012 Multi-University Training Contest 2

http://acm.hdu.edu.cn/showproblem.php?pid=4313

贪心算法:类似kruskal最小生成树的过程,不过此处将边按权值从大到小排列,每次将边加进来时要判断是否会使两个危险的点连通,是的话这条边就是需要被删除的,否则将它加到树上。

还有一种 说是树形DP 不懂

这题一直WA 看了秦老师的代码 用的--int64 就改了下数据类型 过了。。。

并查集+快排+去掉危险的结点

View Code
 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 }

 

posted @ 2012-07-27 09:36  _雨  阅读(174)  评论(2编辑  收藏  举报