最小生成树 HDU1879
第一种克鲁斯卡尔算法(并查集)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 7 using namespace std; 8 9 struct edge 10 { 11 int fro,to,val,sta; 12 bool operator<(edge n)const 13 { 14 return val<n.val; 15 } 16 }e[5010]; 17 int father[110]; 18 19 void init() 20 { 21 for(int i=0;i<110;i++) 22 father[i]=i; 23 } 24 25 int find(int x) 26 { 27 if(x!=father[x]) 28 { 29 father[x]=find(father[x]); 30 } 31 return father[x]; 32 } 33 34 int unio(int x,int y) 35 { 36 int fx=find(x); 37 int fy=find(y); 38 if(fx==fy) 39 return 0; 40 father[fx]=fy; 41 return 1; 42 } 43 44 int main() 45 { 46 int n; 47 while(scanf("%d",&n)!=EOF) 48 { 49 if(n==0) 50 break; 51 init(); 52 for(int i=1;i<=n*(n-1)/2;i++) 53 { 54 scanf("%d%d%d%d",&e[i].fro,&e[i].to,&e[i].val,&e[i].sta); 55 if(e[i].sta==1) 56 { 57 father[e[i].fro]=e[i].to; 58 } 59 } 60 sort(e,e+n*(n-1)/2); 61 int ans=0; 62 for(int i=1;i<=n*(n-1)/2;i++) 63 { 64 if(unio(e[i].fro,e[i].to)) 65 { 66 ans+=e[i].val; 67 } 68 } 69 cout<<ans<<endl; 70 } 71 }
第二种prim算法(迪杰斯特拉最短路)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 7 using namespace std; 8 9 int map[110][110]; 10 bool vis[110]; 11 int div1[110]; 12 int MAX=1<<29; 13 14 int main() 15 { 16 int n; 17 while(scanf("%d",&n)!=EOF) 18 { 19 if(n==0) 20 break; 21 int ans=0; 22 memset(vis,false,sizeof(vis)); 23 for(int i=2;i<=n;i++) 24 { 25 div1[i]=MAX; 26 } 27 int a,b,c,d; 28 for(int i=1;i<=n*(n-1)/2;i++) 29 { 30 scanf("%d%d%d%d",&a,&b,&c,&d); 31 if(d==1) 32 { 33 map[a][b]=map[b][a]=0; 34 } 35 else 36 { 37 map[a][b]=map[b][a]=c; 38 } 39 } 40 div1[1]=0; 41 for(int j=1;j<=n;j++) 42 { 43 int mi=MAX; 44 int v; 45 for(int i=1;i<=n;i++) 46 { 47 if(!vis[i]&&mi>div1[i]) 48 { 49 mi=div1[i]; 50 v=i; 51 } 52 } 53 ans+=div1[v]; 54 vis[v]=true; 55 for(int i=1;i<=n;i++) 56 { 57 if(!vis[i]&&div1[i]>map[v][i]) 58 { 59 div1[i]=map[v][i]; 60 } 61 } 62 } 63 cout<<ans<<endl; 64 } 65 return 0; 66 }