1212 無向圖最小生成樹(prim算法和kruskal算法)


1212 無向圖最小生成樹

基准時間限制:1 秒 空間限制:131072 KB 分值: 0 難度:基礎題
收藏
關注
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 <cstdio>
 4 #include <algorithm>
 5 #define N 1005
 6 #define inf 0x3f3f3f3f
 7 #define mem(a) memset(a,0,sizeof(a))
 8 using namespace std;
 9 int cost[N][N];//表示兩點之間的距離,不存在則設為inf
10 int mincost[N];//從x集合出發到每個頂點的最小值
11 bool used[N];//判斷是否在集合中的布爾數組
12 int n,m;
13 
14 int prim(){
15   for(int i=0;i<n;i++){//初始化mincost數組和used布爾數組
16     mincost[i]=inf;
17     used[i]=false;
18   }
19   mincost[0]=0;//賦給其初值
20   long long int ans=0;
21 
22   while(true){
23     int v=-1;
24     //從不屬於x的頂點中選取從x到其權值最小的頂點
25     for(int u=0;u<n;u++)
26       if(!used[u]&&(v==-1||mincost[u]<mincost[v]))
27         v=u;
28 
29     if(v==-1)
30       break;//條件成立則說明所有的點都已經加入
31     used[v]=true;//把頂點加入
32     ans+=mincost[v];//把邊的長度加到結果里
33 
34     for(int u=0;u<n;u++){
35       if(!used[u])
36         mincost[u]=min(mincost[u],cost[v][u]);
37     }
38   }
39   return ans;
40 }
41 int main(){
42   cin>>n>>m;
43   int x,y,z;
44   memset(cost,inf,sizeof(cost));
45   while(m--){
46     scanf("%d%d%d",&x,&y,&z);
47     cost[--x][--y]=z;
48     cost[y][x]=z;
49   }
50   long long int k=prim();
51   cout<<k<<endl;
52   return 0;
53 }

 kruskal算法解題:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #define N 50005
 6 using namespace std;
 7 struct Node{//定義結構體,分別加入兩個點和兩個點之間的權值
 8   int u,v,cost;
 9 };
10 bool cmp(Node a,Node b){//自定義排序
11   return a.cost<b.cost;
12 }
13 Node node[N];
14 int fa[N];
15 int n,m;
16 int Find(int x){//並查集查找
17   return x==fa[x]?x:Find(fa[x]);
18 }
19 void init(){//初始化fa數組
20   for(int i=0;i<n;i++){
21     fa[i]=i;
22   }
23   return ;
24 }
25 int kruskal(){
26   init();
27   long long int cnt=0;
28   int t=0;
29   for(int i=0;i<m;i++){
30     Node e=node[i];
31     int x=Find(e.u);
32     int y=Find(e.v);
33     if(x!=y){//如果父節點相同,則構成了一個環,那么就不能將其放入里面,跳過
34       fa[x]=y;
35       cnt+=e.cost;
36       t++;
37     }
38     if(t==n-1) break;//如果所加的邊達到了n-1條,跳出循環
39   }
40   return cnt;
41 }
42 int main(){
43   scanf("%d%d",&n,&m);
44   for(int i=0;i<m;i++){
45     scanf("%d%d%d",&node[i].u,&node[i].v,&node[i].cost);
46   }
47   sort(node ,node+m,cmp);
48   long long int ans=kruskal();
49   printf("%lld\n",ans);
50   return 0;
51 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM