3 0 990 692 990 0 179 692 179 0 1 1 2
179
//输入方式:第一行有N个村庄,然后是N行,每行是一个村庄与其他村庄的距离,然后是一个T,表示已经修好的路的条数,求最少还要修多长的路
//Kruscal
#include<cstdio> #include<algorithm> using namespace std; struct node { int u,v,w; int flag; }; bool cmp(node a,node b) { if(a.flag==b.flag) return a.w<b.w; return a.flag>b.flag; } node arr[10000]; int per[110]; int n; 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 f) { int fx=find(x); int fy=find(y); if(fx!=fy) { per[fx]=fy; if(f==1) return 0; return 1; } return 0; } int main() { int a,b,temp; int T; int i,j; while(~scanf("%d",&n)) { init(); int k=0; for(i=1;i<=n;++i) { for(j=1;j<=n;++j) { scanf("%d",&temp); if(temp) { arr[k].u=i; arr[k].v=j; arr[k].flag=0; arr[k++].w=temp; } } } scanf("%d",&T); while(T--) { scanf("%d%d",&a,&b); for(i=0;i<k;++i) { if(arr[i].u==a&&arr[i].v==b) { arr[i].flag=1; break; } } } sort(arr,arr+k,cmp); int sum=0; for(i=0;i<k;++i) { if(join(arr[i].u,arr[i].v,arr[i].flag)) { sum+=arr[i].w; } } printf("%d\n",sum); } return 0; }
//prim
#include<stdio.h> #include<string.h> #define INF 0x3f3f3f3f #define N 110 int n; int i,j; int map[N][N]; int a,b; int low[N]; bool vis[N]; void input() { for(i=1;i<=n;++i) { for(j=1;j<=n;++j) { scanf("%d",map[i]+j); } } int m; scanf("%d",&m); while(m--) { scanf("%d%d",&a,&b); //vis[a]=vis[b]=1;//把已经连接了的两个点加入最小生成树集合 map[a][b]=map[b][a]=0; //把ab两点的权值变为0 } } void prim() { int pos=1; int sum=0; for(i=1;i<=n;++i)//第一次给low赋值 { low[i]=map[pos][i]; } vis[pos]=1; //加入最小生成树集合 for(i=1;i<n;++i)//再找n-1个点 { int min=INF; for(j=1;j<=n;++j) { if(!vis[j]&&min>low[j]) { min=low[j]; pos=j;//把找到的点记录下 } } sum+=min; vis[pos]=1; for(j=1;j<=n;++j) { if(!vis[j]&&low[j]>map[pos][j]) { low[j]=map[pos][j]; } } } printf("%d\n",sum); } int main() { while(~scanf("%d",&n)) { memset(vis,0,sizeof(vis)); input(); prim(); } return 0; }