標籤:os io for ar 代碼 amp 演算法 size
題意:n個農場,求把所有農場串連起來所需要最短的距離。
思路:prim演算法
課本代碼:
//prim演算法#include<iostream>#include<stdio.h>#include<cstring>using namespace std;int n;int tot;int v[150][150];int dist[150];//存 節點到樹 的最小距離bool use[150];//標記節點是否存在int main(){while(scanf("%d",&n)!=EOF){memset(use,false,sizeof(use));//初始化節點 都存在tot=0;use[0]=1;int i,j,k;for(i=0;i<n;i++)for(j=0;j<n;j++)scanf("%d",&v[i][j]);dist[0]=0x7FFFFFFF;//賦值為最大值for(i=1;i<n;i++)//初始距離dist[i]=v[0][i];for(i=1;i<n;i++){//串連 剩下的 n-1個節點int tmp=0;for(k=1;k<n;k++)//找到最短的距離 節點if(dist[k]<dist[tmp] &&!use[k]) tmp=k;tot +=dist[tmp];// 加到 總距離中use[tmp]=true;for(k=1;k<n;k++)//調整距離if(!use[k])dist[k]=v[k][tmp]<dist[k]?v[k][tmp]:dist[k];}printf("%d\n",tot);}return 0;}
另外,這道題也可以用 Kruskal演算法,代碼如下:
//Kruskal演算法#include<iostream>using namespace std;int fa[120];int get_father(int x){return fa[x]=fa[x]==x?x:get_father(fa[x]);//判斷兩個節點是否屬於一顆子樹(並查集)}int main(){int n;int p[120][120];int mark[100100];while(scanf("%d",&n)!=EOF){memset(mark,0,sizeof(mark));int i,j,k,m;for(i=0;i<n;i++)for(j=0;j<n;j++){scanf("%d",&p[i][j]);mark[p[i][j]]=1;}for(i=0;i<n;i++) fa[i]=i;int ans=0;for(k=1;k<=100000;k++)// kruskal 演算法if(mark[k]){// 若不加mark ,會逾時for(i=0;i<n;i++)for(int j=0;j<n;j++)if(p[i][j]==k &&get_father(i)!=get_father(j)){fa[fa[i]]=fa[j];//合并兩顆子樹(並查集)ans+=k;}}printf("%d\n",ans);}return 0;}