基准時間限制: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 }