T78748 【lcez模拟赛】机场Ⅰ
其实这就是最小生成树的题辣
注意输入毒瘤
输入的话要避免记录中间这个‘ , ’
如下操作可以解决
特别注意%d之间的‘ , ’
边的权值要现算
存点的话存横纵坐标
注意本题是进行好多次询问,模块化一下吧
放代码
#include<bits/stdc++.h> using namespace std; int T,n,m,fa[1001]; int find(int x) { if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } struct egg { int x,y; }point[1001]; struct edge { int from,to; double dis; }Edge[20001]; bool cmp(edge a,edge b) { return a.dis <b.dis; } double dis(egg a,egg b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } void klske() { int flag=0; int k=0; double ans=0; for(int i=1;i<=n;i++) fa[i]=i; sort(Edge+1,Edge+m+1,cmp); for(int i=1;i<=m&&k<=n-1;i++) { int f1=find(Edge[i].from) ; int f2=find(Edge[i].to) ; if(f1!=f2) { ans+=Edge[i].dis; fa[f1]=f2; k++; } if(k==n-1) { flag=1; printf("%.4lf ",ans); break; } } if(!flag) printf("orz "); } void caozuo() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d,%d",&point[i].x ,&point[i].y ); for(int i=1;i<=m;i++) { scanf("%d%d",&Edge[i].from ,&Edge[i].to ); Edge[i].dis=dis(point[Edge[i].from] ,point[Edge[i].to]); } klske(); } int main() { scanf("%d",&T); for(int i=1;i<=T;i++) caozuo(); }