3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
3 ?
//Kruscal
#include<cstdio> #include<algorithm> using namespace std; struct node { int u,v,w; }; node arr[10000]; int per[110]; int n; bool cmp(node a,node b) { return a.w<b.w; } void init() { for(int i=1;i<=n;++i) { per[i]=i; } } int find(int x) { if(x==per[x]) return x; return per[x]=find(per[x]); } bool join(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) { per[fx]=fy; return 1; } return 0; } int main() { int m,i; while(~scanf("%d",&m),m) { scanf("%d",&n); init(); for(i=0;i<m;++i) { scanf("%d%d%d",&arr[i].u,&arr[i].v,&arr[i].w); } sort(arr,arr+m,cmp); int sum=0; for(i=0;i<m;++i) { if(join(arr[i].u,arr[i].v)) { sum+=arr[i].w; } } int cnt=0,flag=0; for(i=1;i<=n;++i) { if(per[i]==i) cnt++; if(cnt>1) { flag=1; break; } } if(!flag)printf("%d\n",sum); else printf("?\n"); } return 0; }
//Prim
#include <stdio.h> #include <string.h> #define N 110 #define INF 0x3f3f3f3f int n,m;//n为村庄个数,m为路 int i,j; int map[N][N]; bool vis[N];//标记是否已经放入最小生成树的那个集合里了 int low[N];//记录不在已经加入最小生成树的这个集合里的元素到这个 集合的最小距离 int u,v,w; void input() { memset(map,INF,sizeof(map)); for(i=1;i<=m;++i) { scanf("%d%d%d",&u,&v,&w); map[u][v]=map[v][u]=w; } } void prim() { int sum=0; memset(vis,0,sizeof(vis)); int pos=1;//从1开始 for(i=1;i<=n;++i)//第一次给low赋值 { low[i]=map[1][i]; } vis[1]=1; //已经找到一个点1,再找n-1个 for(i=1;i<n;++i) { int min=INF; for(j=1;j<=n;++j) { if(!vis[j]&&min>low[j])//找下一个点到这个集合的最小值 { min=low[j];//记下这个最小值 pos=j;//记下这个点 } } if(min==INF) { printf("?\n"); return ; } sum+=min; vis[pos]=1;//把刚刚找到的这个点加入集合 for(j=1;j<=n;++j) //更新low数组 { if(!vis[j]&&low[j]>map[pos][j]) { low[j]=map[pos][j]; } } } printf("%d\n",sum); } int main() { while(~scanf("%d%d",&m,&n),m) { input(); prim(); } return 0; }