1.Question:
題意:
輸入:n,m
n代表已經點個數,m表示有多少條邊已經連接成功
本題是一個稠密圖,每兩個點之間都有邊相連
之後的輸入的代表兩個點之間有連邊
輸出:
最小的需求,本題是一個稠密圖
2.Solution:
因爲是稠密圖,本題的Krustral沒有Prim快
本題是一個Prim的版題,但是不知道爲什麼,可能是精度的問題,導致的已知在WA
之後莫名其妙的AC
我們的已經存在的連邊,我們只要在稠密圖中優先連接就可以了
3.Code:
#include"iostream"
#include"cstdio"
#include"cstdlib"
#include"cstring"
#include"cmath"
#define INF 0x3f3f3f3f
#define N 1010
using namespace std;
typedef struct node
{
double x,y;
}point;
double map[N][N];
double dis[N];
int n,m;
point save[N];
int book[N];
double cal(int i,int j)
{
double vx=(save[i].x-save[j].x)*(save[i].x-save[j].x);
double vy=(save[i].y-save[j].y)*(save[i].y-save[j].y);
return sqrt(vx+vy+0.0);
}
double prim()
{
memset(dis,0,sizeof(dis));
memset(book,0,sizeof(book));
double sum=0;
for(int i=1;i<=n;i++)
{
dis[i]=map[1][i];
}
dis[1]=0;
book[1]=1;
for(int i=1;i<=n;i++)
{
double mink=100000000;
int minpoint;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&dis[j]<mink)
{
mink=dis[j];
minpoint=j;
}
}
if(mink==100000000) break;
book[minpoint]=1;
sum+=mink;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&dis[j]>map[minpoint][j])
{
dis[j]=map[minpoint][j];
}
}
}
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
map[i][j]=100000000;
}
}
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&save[i].x,&save[i].y);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
map[i][j]=cal(i,j);
}
for(int i=1;i<=m;i++)
{
int dx,dy;
scanf("%d%d",&dx,&dy);
map[dx][dy]=map[dy][dx]=0;
}
double kk=prim();
printf("%.2lf\n",kk);
return 0;
}