用Prim算法就好。
代码如下:
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1e3+5;
struct edge
{
int fro,to;
}e1[maxn];
int x[maxn],y[maxn],map[maxn][maxn],dis[maxn];
bool vis[maxn];
int clo[maxn],cnt1;
void Prim(int n)
{
for(int i=1;i<=n;i++)
{
vis[i]=0;
clo[i]=1;
dis[i]=map[1][i];
}
vis[1]=1;
for(int i=1;i<=n;i++)
{
int temp=100000000+5;
int k;
for(int j=1;j<=n;j++)
if(!vis[j]&&temp>dis[j])
{
k=j;
temp=dis[j];
}
if(temp==100000000+5)
break;
edge a;
a.fro=clo[k];a.to=k;
vis[k]=1;
if(a.fro>a.to) swap(a.fro,a.to);
e1[cnt1++]=a;
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[j]>map[k][j])
{
clo[j]=k;
dis[j]=map[k][j];
}
}
for(int i=0;i<cnt1;i++)
{
if(map[e1[i].fro][e1[i].to])
cout<<e1[i].fro<<' '<<e1[i].to<<endl;
}
}
int main()
{
int n,m;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
map[i][i]=0;
for(int j=1;j<i;j++)
{
int d;
d=(x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i]);
map[i][j]=map[j][i]=d;
}
}
cin>>m;
cnt1=0;
while(m--)
{
edge a;
cin>>a.fro>>a.to;
if(a.fro>a.to) swap(a.fro,a.to);
map[a.fro][a.to]=map[a.to][a.fro]=0;
}
Prim(n);
return 0;
}
表示非常讨厌这道题,没有说明只有一组数据,结果我加了while(cin>>n)一直RE,还有非常蜜汁的WA,一开始我是有讲边按起点从小到大排序的,最后再输出,结果过不了,虽说是多此一举了,但似乎也没什么错的啊。
下面是我原先的代码:
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1e3+5;
struct edge
{
int fro,to;
}e1[maxn],e2[maxn];
bool cmp(edge a,edge b)
{
if(a.fro!=b.fro)
return a.fro<b.fro;
return a.to<b.to;
}
int x[maxn],y[maxn],map[maxn][maxn],dis[maxn];
bool vis[maxn];
int clo[maxn],cnt1,cnt2;
void Prim(int n)
{
for(int i=1;i<=n;i++)
{
vis[i]=0;
clo[i]=1;
dis[i]=map[1][i];
}
vis[1]=1;
for(int i=1;i<=n;i++)
{
int temp=100000000+5;
int k;
for(int j=1;j<=n;j++)
if(!vis[j]&&temp>dis[j])
{
k=j;
temp=dis[j];
}
if(temp==100000000+5)
break;
edge a;
a.fro=clo[k];a.to=k;
vis[k]=1;
if(a.fro>a.to) swap(a.fro,a.to);
e1[cnt1++]=a;
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[j]>map[k][j])
{
clo[j]=k;
dis[j]=map[k][j];
}
}
sort(e1,e1+cnt1,cmp);
for(int j=0,i=0;i<cnt1;i++)
{
if(j<cnt2)
{
if(e1[i].fro!=e2[j].fro||e1[i].to!=e2[j].to)
{
flag=0;
cout<<e1[i].fro<<' '<<e1[i].to<<endl;
}
else j++;
}
else
{
flag=0;
cout<<e1[i].fro<<' '<<e1[i].to<<endl;
}//cout<<e1[i].fro<<' '<<e1[i].to<<" "<<e2[j].fro<<' '<<e2[j].to<<endl;
}
}
int main()
{
int n,m;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
map[i][i]=0;
for(int j=1;j<i;j++)
{
int d;
d=(x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i]);
map[i][j]=map[j][i]=d;
}
}
cin>>m;
cnt1=cnt2=0;
while(m--)
{
edge a;
cin>>a.fro>>a.to;
if(a.fro>a.to) swap(a.fro,a.to);
map[a.fro][a.to]=map[a.to][a.fro]=0;
e2[cnt2++]=a; //记录下已经建好了的路,方便后面进行比对
}
sort(e2,e2+cnt2,cmp);
/*for(int j=0;j<cnt2;j++)
cout<<e2[j].fro<<' '<<e2[j].to<<endl;*/
Prim(n);
return 0;
}