当前位置: 代码迷 >> 综合 >> HDU 1875 畅通工程再续 (最小生成树)
  详细解决方案

HDU 1875 畅通工程再续 (最小生成树)

热度:86   发布时间:2023-11-06 18:38:55.0

题意:

注意把距离小于10米和距离大于1000的两个岛的距离设置为无穷大,调用prim函数结束后检查一下图是否连通即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
const int N=105;
#define inf 0x3f3f3f3f
int n,vis[N];
double dis[N],ma[N][N],cost;
struct {int x,y;
}is[N];
double qiu(int x1,int y1,int x2,int y2){double te=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);return sqrt(te); 
}
void mem(){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){double te=qiu(is[j].x,is[j].y,is[i].x,is[i].y);	if(i==j) ma[i][j]=0;else if(te<10||te>1000) ma[i][j]=inf;else ma[i][j]=te;}
} 
void prim(){for(int i=1;i<=n;i++){dis[i]=ma[1][i];vis[i]=0;}dis[1]=0;vis[1]=1;for(int i=1;i<=n;i++){double mi=inf;int mb;for(int j=1;j<=n;j++){if(!vis[j]&&dis[j]<mi){mi=dis[j];mb=j;}}if(mi==inf) break;vis[mb]=1;cost+=dis[mb];for(int i=1;i<=n;i++){if(!vis[i]&&ma[mb][i]<dis[i]){dis[i]=ma[mb][i];}}}}
int main(){int T;scanf("%d",&T);while(T--){cost=0;scanf("%d",&n);int a,b;for(int i=1;i<=n;i++){scanf("%d%d",&a,&b);is[i].x=a;is[i].y=b;}mem();prim(); int flag=1;for(int i=1;i<=n;i++){if(!vis[i]) {flag=0;break;}}if(flag)printf("%.1lf\n",cost*100);else puts("oh!");}return 0;
}