51NOD 1212 最小生成树模板

1212 无向图最小生成树

N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。

Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Input示例
9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
Output示例
37

模板题
Prim
邻接表
 1 #include <iostream>//邻接表
 2 #include <cstring>
 3 #include <vector>
 4 #define inf 0x3f3f3f3f
 5 using namespace std;
 6 int n,m;
 7 struct node{
 8     int to,num;
 9 };
10 vector<node> v[1010];
11 int prim(){
12     node d;
13     bool visit[1010];
14     int len[1010];
15     int sum=0;
16     memset(visit,false,sizeof(visit));
17     memset(len,inf,sizeof(len));
18     visit[1]=true;
19     for(int i=0;i<v[1].size();i++){
20         d=v[1][i];
21         //cout<<d.to<<" = "<<d.num<<endl;
22         len[d.to]=d.num;
23     }
24     for(int j=1;j<n;j++){
25         int nn=-1;
26         for(int i=1;i<=n;i++){
27             //cout<<len[i]<<" ";
28             if(!visit[i]&&(nn==-1||len[i]<len[nn])){
29                 nn=i;
30             }
31         }
32         //cout<<endl;
33         if(nn==-1){
34             return -1;
35         }
36         sum+=len[nn];
37         visit[nn]=true;
38         for(int i=0;i<v[nn].size();i++){
39             d=v[nn][i];
40             if(!visit[d.to]&&len[d.to]>d.num){
41                 len[d.to]=d.num;
42             }
43         }
44     }
45     return sum;
46 }
47 int main(){
48     cin.sync_with_stdio(false);
49     int a,b,c;
50     while(cin>>n>>m){
51         for(int i=1;i<=n;i++){
52             v[i].clear();
53         }
54         for(int i=0;i<m;i++){
55             cin>>a>>b>>c;
56             node d;
57             d.to=b;
58             d.num=c;
59             v[a].push_back(d);
60             d.to=a;
61             v[b].push_back(d);
62         }
63         cout<<prim()<<endl;
64     }
65     return 0;
66 }

 

Prim
邻接矩阵

 1 #include <iostream>//邻接矩阵
 2 #include <cstring>
 3 #define inf 0x3f3f3f3f
 4 using namespace std;
 5 int n,m;
 6 int mapp[1010][1010];
 7 int prim(){
 8     bool visit[1010];
 9     int len[1010];
10     int sum=0;
11     memset(visit,false,sizeof(visit));
12     visit[1]=true;
13     for(int i=1;i<=n;i++){
14         len[i]=mapp[1][i];
15     }
16     for(int j=1;j<n;j++){
17         int nn=-1;
18         for(int i=1;i<=n;i++){
19             if(!visit[i]&&(nn==-1||len[i]<len[nn])){
20                 nn=i;
21             }
22         }
23         //cout<<endl;
24         if(nn==-1){
25             return -1;
26         }
27         sum+=len[nn];
28         visit[nn]=true;
29         for(int i=1;i<=n;i++){
30             if(!visit[i]&&len[i]>mapp[nn][i]){
31                 len[i]=mapp[nn][i];
32             }
33         }
34     }
35     return sum;
36 }
37 int main(){
38     cin.sync_with_stdio(false);
39     int a,b,c;
40     while(cin>>n>>m){
41         memset(mapp,inf,sizeof(mapp));
42         for(int i=0;i<m;i++){
43             cin>>a>>b>>c;
44             mapp[a][b]=c;
45             mapp[b][a]=c;
46         }
47         cout<<prim()<<endl;
48     }
49     return 0;
50 }

 

posted @ 2016-12-06 20:24  ガ落涙『不變』  阅读(78)  评论(0编辑  收藏  举报