题意:给定N个城市的坐标,然后下面给出M个已经连接好的城市标号,求他们之间的最小生成树,其中,已连接的话,不必输出。
思路:将已给的城市之间距离标为0,输出的时候,城市之间为零的就不必输出。
#include "stdio.h"
#include "string.h"
#include "queue"
#include "iostream"
#include "functional"
#include "math.h"
#include "algorithm"
using namespace std;
const int maxn = 855;
const int mod = 1000000007 ;
const int inf = 1<<30;
typedef __int64 LL;
typedef pair<double,int> pii;
int n,m,ans,mst;
double map[maxn][maxn],dis[maxn];
int pre[maxn];
struct node
{
int x,y;
}city[maxn];
double Get_Dis( node a,node b )
{
return sqrt( ((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y))*1.0 );
}
int prime( int s )
{
int ans = 0;
priority_queue<pii,vector<pii>,greater<pii> >que;
dis[s] = 0;
pre[s] = -1;
que.push( make_pair( dis[s],s ) );
while( !que.empty() )
{
pii u = que.top(); que.pop();
int x = u.second;
if( dis[x] != 0 )
printf("%d %d\n",x,pre[x]);
for( int i = 1; i <= n; i ++ )
{
if( dis[i] > map[x][i] )
{
dis[i] = map[x][i];
que.push( make_pair( dis[i],i ) );
pre[i] = x;
}
}
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.txt","r",stdin);
#endif
int x,y;
while( scanf("%d",&n) != EOF )
{
for( int i = 1; i <= n; i ++ ){
scanf("%d%d",&city[i].x,&city[i].y);
dis[i] = inf;
}
for( int i = 1; i <= n; i ++ )
{
for( int j = i; j <= n; j ++ )
{
map[i][j] = map[j][i] = Get_Dis( city[i],city[j] );
}
}
scanf("%d",&m);
for( int i = 0; i < m; i ++ )
{
scanf("%d%d",&x,&y);
map[x][y] = map[y][x] = 0;
}
prime( 1 );
}
return 0;
}