链接:http://poj.org/problem?id=2421
题意:n个村庄,告诉你任两个村庄间距离,要建一些路使得任两个村庄都可以互相到达,需要使花费最小,其中有q条路已经建了,求最小花费。
把已经建的路的权值改为0,再prim就行了。kruskal做的话,把建好的路用并查集合并,再kruskal就行了
#include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cctype> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<stack> #include<ctime> #include<cstdlib> #include<functional> #include<cmath> using namespace std; #define PI acos(-1.0) #define MAXN 110 #define eps 1e-7 #define INF 0x7FFFFFFF #define seed 131 #define ll long long #define ull unsigned ll #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int edge[MAXN][MAXN],vis[MAXN],dist[MAXN]; int n,m,ans; void prim(){ int i,j; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++) dist[i] = edge[1][i]; vis[1] = 1; for(i=0;i<n-1;i++){ int temp = INF,k = -1; for(j=1;j<=n;j++){ if(!vis[j]&&dist[j]<temp){ temp = dist[j]; k = j; } } if(k==-1) break; vis[k] = 1; ans += dist[k]; for(j=1;j<=n;j++){ if(!vis[j]&&edge[k][j]<dist[j]) dist[j] = edge[k][j]; } } } int main(){ int i,j,q,a,b; int x; while(scanf("%d",&n)!=EOF){ ans = 0; for(i=0;i<n;i++){ for(j=0;j<n;j++){ scanf("%d",&edge[i+1][j+1]); } } scanf("%d",&q); while(q--){ scanf("%d%d",&a,&b); edge[a][b] = edge[b][a] = 0; } prim(); printf("%d\n",ans); } return 0; }
POJ--2421--Constructing Roads【最小生成树】,布布扣,bubuko.com
POJ--2421--Constructing Roads【最小生成树】
原文:http://blog.csdn.net/zzzz40/article/details/38372725