HDU 1863 畅通工程

法一:
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1863
1
#include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int parent[105]; 7 struct Edge{ 8 int from,to,price; 9 }edge[5100]; 10 bool compare(Edge a,Edge b){ 11 return a.price<b.price; 12 } 13 void init(int n){ 14 for(int i=1;i<=n;i++) 15 parent[i]=i; 16 17 } 18 int find(int x){ 19 while(x!=parent[x]) 20 x=parent[x]; 21 return x; 22 } 23 void merge(int x,int y){ 24 x=find(x); 25 y=find(y); 26 parent[x]=y; 27 } 28 int main(){ 29 int sum,m,n; 30 while(scanf("%d %d",&n,&m)&&n){ 31 init(m); 32 sum=0; 33 for(int i=1;i<=n;i++) 34 scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].price); 35 sort(edge+1,edge+n+1,compare); 36 for(int i=1;m>1&&i<=n;i++){ 37 int x=find(edge[i].from),y=find(edge[i].to); 38 if(x!=y){ 39 merge(x,y); 40 m--; 41 sum+=edge[i].price; 42 } 43 } 44 if(m==1){ 45 printf("%d\n",sum); 46 } 47 else 48 printf("?\n"); 49 } 50 return 0; 51 }
 1 /*法二:(最小生成树kruskal)
2   Name: hdu1863畅通工程 

 3   Author: myc

 4   Date:20120807

 5   Description: 最小生成树(kruskal) 

 6 */

 7 #include <cstdio>

 8 #include <iostream>

 9 

10 using namespace std;

11 

12 const int M = 5050;

13 

14 int p[M], sum; //sum统计顶点个数 

15 struct edge {

16     int a;

17     int b;

18     int w;

19 }e[M];

20 

21 int cmp(const void *a, const void *b) {

22     return (*(edge *)a).w - (*(edge *)b).w;

23 } 

24 

25 void init(int vs) {

26     for (int i=1; i<=vs; ++i) p[i] = i;

27     return ;

28 }

29 

30 int find(int v) {

31     if (p[v] != v) p[v] = find(p[v]);

32     return p[v];

33 }

34 

35 int join(edge e) {

36     int x, y;

37     x = find(e.a);

38     y = find(e.b);

39     if (x != y) {

40         ++sum;

41         p[x] = y;

42         return e.w;

43     }

44     return 0;

45 }

46 

47 int kruskal(int es, int vs) {

48     int ans = 0;

49     init(vs);

50     qsort(e, es, sizeof(edge), cmp);

51     for (int i=0; i<es; ++i) {

52         ans += join(e[i]);

53         if (sum == vs) return ans;

54     }

55     if (sum < vs) return -1;

56 }

57 

58 int main() {

59     int n, m;

60     while (scanf("%d%d", &n, &m), n) {

61         sum = 1;

62         for (int i=0; i<n; ++i) scanf ("%d%d%d", &e[i].a, &e[i].b, &e[i].w);

63         int ans = kruskal(n, m);

64         if (ans == -1) printf ("?\n");

65         else printf ("%d\n", ans);

66     }

67     return 0;

68 }
 1 法三:裸的最小生成树,只需多判断一下是否连通,我用的方法是看是否只有一个根节点。

 3 #include <stdio.h>

 4 #include <stdlib.h>

 5 #include <string.h>

 6 int idx[1000000];

 7 struct node{

 8     int a,b,cost;

 9 }r[1000000];

10 int cmp(const void*a,const void*b)

11 {

12     return (*(struct node*)a).cost-(*(struct node*)b).cost;

13 }

14 int find(int n)

15 {

16     return idx[n]==n?n:idx[n]=find(idx[n]);

17 }

18 int main()

19 {

20     int i,n,m;

21     int p,q;

22     int f;

23     while(scanf("%d",&n),n)

24     {

25         scanf("%d",&m);

26         for(i=1;i<=m;i++)

27             idx[i]=i;

28         for(i=0;i<n;i++)

29             scanf("%d%d%d",&r[i].a,&r[i].b,&r[i].cost);

30         qsort(r,n,sizeof(struct node),cmp);

31         int cost=0;

32         for(i=0;i<n;i++)

33         {

34             p=find(r[i].a);

35             q=find(r[i].b);

36             if(p!=q)

37             {

38                 cost+=r[i].cost;

39                 idx[p]=q;

40             }

41         }

42         f=0;

43         for(i=1;i<=m;i++)

44             if(find(i)==i)

45                 f++;

46         if(f>1)

47             printf("?\n");

48         else

49             printf("%d\n",cost);

50     }

51     return 0;

52 }

你可能感兴趣的:(HDU)