最小生成树直接prim就行了, 最小生成树中一些边(给定)是必须在树里面的. 求树的剩余边
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define m 99999999
struct Closedge
{
int adj;
double lowcost;
}closedge[800];
struct Point
{
int x,y;
}p[800];
struct Points
{
int x;
int y;
};
struct Points p2[800];
double map[800][800];
int mycompare(const void *elem1,const void *elem2)
{
return (*(struct Points *)elem1).x-(*(struct Points *)elem2).x;
}
int prime(int n)
{
int i,j,k,t=0;
double min=99999999;
k=1;
for(i=1;i<=n;i++)
{
if(i!=k)
{
closedge[i].adj=k;
closedge[i].lowcost=map[k][i];
}
}
closedge[k].lowcost=0;
for(i=1;i<n;i++)
{
min=99999999;
for(j=1;j<=n;j++)
{
if(closedge[j].lowcost!=0)
{
if(closedge[j].lowcost<min)
{
min=closedge[j].lowcost;
k=j;
}
}
}
if(min!=-1 && min<99999999)
{
if(closedge[k].adj>k)
{
p2[t].x=k;
p2[t].y=closedge[k].adj;
}
else
{
p2[t].x=closedge[k].adj;
p2[t].y=k;
}
//cout<<p2[t].x<<" "<<p2[t].y<<endl;
t++;
}
closedge[k].lowcost=0;
for(j=1;j<=n;j++)
{
if(map[k][j]<closedge[j].lowcost && closedge[j].lowcost!=0)
{
closedge[j].adj=k;
closedge[j].lowcost=map[k][j];
}
}
}
return t;
}
int main()
{
int n,i,j,e,f,r;
double dis,a,b;
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=m;
for(i=1;i<=n;i++)
scanf("%d %d",&p[i].x,&p[i].y);
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
a=(double)p[i].x-(double)p[j].x;
b=(double)p[i].y-(double)p[j].y;
dis=sqrt(a*a+b*b);
map[i][j]=map[j][i]=dis;
}
}
scanf("%d",&r);
for(i=1;i<=r;i++)
{
scanf("%d %d",&e,&f);
map[e][f]=map[f][e]=-1;
}
e=prime(n);
qsort(p2,e,sizeof(struct Points),mycompare);
for(i=0;i<e;i++)
printf("%d %d/n",p2[i].x,p2[i].y);
return 0;
}