法一:
地址: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 }