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 }

posted on 2012-08-07 16:43  mycapple  阅读(313)  评论(0)    收藏  举报

导航