最小生成树

畅通工程

题目描述:

某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。

 

input:
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。 
当N为0时,输入结束,该用例不被处理。

 

output:

对每个测试用例,在1行里输出最小的公路总长度。

 

Sample input

3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0

Sample output

3
5

 1 #include<bits/stdc++.h>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<stack>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<deque>
11 #include<vector>
12 #include<iostream>
13 #include<algorithm>
14 using namespace std;
15 #define ll long long
16 #define pi acos(-1)
17 #define eps 1e-10
18 #define LC(a) (a<<1)
19 #define RC(a) (a<<1|1)
20 #define MID(a,b) ((a+b)>>1)
21 #define mem(x) memset(x,0,sizeof(x))
22 #define si(n) scanf("%d",&n)
23 #define _f(x,y,z) for(int (x)=(y);(x)<=(z);(x)++)
24 #define __f(x,y,z) for(int (x)=(y);(x)>=(z);(x)--)
25 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
26 ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
27 ll powmod(ll a,ll b,ll MOD)
28 {ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
29 template< typename T > inline void read(T &x) {
30     static bool fr_f; static char fr_ch;
31    fr_f=0; x=0; fr_ch=getchar();
32     while(fr_ch<'0' || '9'<fr_ch) {if(fr_ch=='-') fr_f=1; fr_ch=getchar();}
33     while('0'<=fr_ch && fr_ch<='9') {x=(x<<1)+(x<<3)+fr_ch-'0'; fr_ch=getchar();}
34     if(fr_f) x=-x;
35 }
36 const int MAXN=1000005;
37 const int MOD=1e9+7;
38 int root[MAXN];
39 const int N=105;
40 const int INF=0x3f3f3f3f;
41 
42 int n;
43 int low[N],dis[N][N];
44 bool vis[N];
45 
46 //Prim算法求最小生成树 
47 int prime(){
48     memset(vis,false,sizeof(vis));
49     int ans=0,cnt=0;//ans记录边长距离和,cnt记录连接的边数 
50     _f(i,1,n) {
51         low[i]=dis[1][i];
52     }
53     vis[1]=true;
54     while(true) {
55         int k=-1;
56         _f(i,1,n) {
57             if(!vis[i]&&(k==-1||low[i]<low[k])) {
58                 k=i;
59             }
60         }
61         if(k==-1||low[k]==INF) break;
62         
63         vis[k]=true;
64         ans+=low[k];
65         cnt++;
66         _f(i,1,n) {
67             if(low[i]>dis[k][i]) 
68                 low[i]=dis[k][i];
69         }
70     }
71     if(cnt==n-1) return ans;
72     return -1;
73 }
74 
75 int main() {
76     while(cin>>n&&n) {
77         memset(dis,INF,sizeof(dis));
78         int a,b,c;
79         _f(i,1,n*(n-1)/2) {
80             cin>>a>>b>>c;
81             dis[a][b]=dis[b][a]=c;
82         }
83         cout<<prime()<<endl;;
84     }
85     return 0;
86 }
最小生成树_Prime

 

 1 #include<bits/stdc++.h>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<stack>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<deque>
11 #include<vector>
12 #include<iostream>
13 #include<algorithm>
14 using namespace std;
15 #define ll long long
16 #define pi acos(-1)
17 #define eps 1e-10
18 const int INF=1<<30;
19 #define LC(a) (a<<1)
20 #define RC(a) (a<<1|1)
21 #define MID(a,b) ((a+b)>>1)
22 #define mem(x) memset(x,0,sizeof(x))
23 #define si(n) scanf("%d",&n)
24 #define _f(x,y,z) for(int (x)=(y);(x)<=(z);(x)++)
25 #define __f(x,y,z) for(int (x)=(y);(x)>=(z);(x)--)
26 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
27 ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
28 ll powmod(ll a,ll b,ll MOD)
29 {ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
30 template< typename T > inline void read(T &x) {
31     static bool fr_f; static char fr_ch;
32    fr_f=0; x=0; fr_ch=getchar();
33     while(fr_ch<'0' || '9'<fr_ch) {if(fr_ch=='-') fr_f=1; fr_ch=getchar();}
34     while('0'<=fr_ch && fr_ch<='9') {x=(x<<1)+(x<<3)+fr_ch-'0'; fr_ch=getchar();}
35     if(fr_f) x=-x;
36 }
37 const int inf=0x3f3f3f3f;
38 const int MAXN=1000005;
39 const int MOD=1e9+7;
40 int root[MAXN];
41 
42 struct node{
43     int x,y,dis;
44 }arr[MAXN];
45 
46 int find(int x) {
47     return x==root[x]?x:root[x]=find(root[x]);
48 }
49 
50 bool cmp(node a, node b) {
51     return a.dis<b.dis;
52 }
53 
54 int kruskal(int n) {
55     _f(i,1,n) {
56         root[i]=i;
57     } 
58     int ans=0,cnt=0;
59     sort(arr+1,arr+1+n*(n-1)/2,cmp);
60     _f(i,1,n*(n-1)/2) {
61         int x=find(arr[i].x);
62         int y=find(arr[i].y);
63         if(x!=y) {
64             root[x]=y;
65             ans+=arr[i].dis;
66             cnt++;
67         }
68           //n个顶点,n-1条边 
69     }return ans;
70 //    return -1;//边不够 
71 }
72 int main() {
73     int n;
74     while(cin>>n&&n) {
75         _f(i,1,n*(n-1)/2) {
76             cin>>arr[i].x>>arr[i].y>>arr[i].dis;
77         }
78         int ans=kruskal(n);
79         cout<<ans<<endl;
80     }
81 }
最小生成树_Kruskal

 




 

posted @ 2018-07-29 22:47  明楼  阅读(82)  评论(0)    收藏  举报