题意:求最小生成树,只不过有一部分已经连接好了。
思路:将连接好的城镇的边赋值为0,直接求最小生成树,权值为0的不输出即可。
代码:
#include <iostream>
#include <cstring>
#include <climits>
#include <cmath>
using namespace std;
struct point{
int x,y;
};
const int maxn = 800;
int n,m;
point a[maxn];
double edge[maxn][maxn];
double lowcost[maxn];
int nearvex[maxn];
double Dis(point &a, point &b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void Init(){
cin>>n;
for(int i = 1; i <= n; i++){
cin>>a[i].x>>a[i].y;
}
for(int i = 1; i <= n-1; i++){
for(int j = i; j <= n; j++){
if(i == j) edge[i][j] = -1;
else edge[i][j] = edge[j][i] = Dis(a[i],a[j]);
}
}
cin>>m;
for(int i = 0; i < m; i++){
int u,v;
cin>>u>>v;
edge[u][v] = edge[v][u] = 0;
}
}
void Prim(){
for(int i = 1; i <= n; i++){
lowcost[i] = edge[1][i];
nearvex[i] = 1;
}
lowcost[1] = -1;
for(int i = 0; i < n-1; i++){
double min = 9999999.0;
int v = -1;
for(int j = 1; j <= n; j++){
if(lowcost[j] != -1 && lowcost[j] < min){
v = j; min = lowcost[j];
}
}
if(v == -1) break;
lowcost[v] = -1;
if(min != 0)
cout<<nearvex[v]<<" "<<v<<"\n";
for(int j = 1; j <= n; j++){
if(edge[v][j] < lowcost[j]){
lowcost[j] = edge[v][j];
nearvex[j] = v;
}
}
}
}
int main(){
int t;
cin>>t;
while(t--){
Init();
Prim();
if(t)
cout<<"\n";
}
return 0;
}