K - Smooth Traffic Project adjourned
Link Title
Title effect: it takes the shortest route calculation communication, but to satisfy the distance between two points is not less than 10 and not more than 1000, if not in communication, outputs OH! , You can output the least cost.
Ideas: minimum spanning tree problem, but not directly set the template prim, do some minor modifications, the details look at the code.
Code
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;
const int MAX=105;
const int inf=999999999;
double cost[MAX][MAX],mincost[MAX];
int n;
bool used[MAX];
struct point{
double x,y;
}e[MAX];
double prim(){
double res=0;
mincost[0]=0;
int cnt=0;
while(true){
int v=-1;
for(int i=0;i<n;i++){
if(!used[i]&&(v==-1||mincost[i]<mincost[v])) v=i;
}
if(v==-1||(v!=0&&mincost[v]==inf)) break;//如果所有点都已经用过或者无法继续连通了,就退出。
cnt++;//计数器,cnt-1就是最小生成树的边数。
used[v]=true;
res+=mincost[v];
for(int i=0;i<n;i++)
mincost[i]=min(mincost[i],cost[v][i]);
}
if(cnt==n) return res;//如果cnt-1==n,就说明可以连通。(最小生成树边数=顶点数-1)
else return -1;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
fill(mincost,mincost+MAX,inf);
fill(used,used+MAX,false);
for(int i=0;i<n;i++){
scanf("%lf%lf",&e[i].x,&e[i].y);
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cost[i][j]=sqrt((e[i].x-e[j].x)*(e[i].x-e[j].x)+(e[i].y-e[j].y)*(e[i].y-e[j].y));
if(cost[i][j]<10||cost[i][j]>1000) cost[i][j]=inf;//如果边权大于1000或小于10,则不存在该边,设为inf。
}
}
double res=prim();
if(res==-1) puts("oh!");
else{
res=res*100;
printf("%.1f\n",res);
}
}
return 0;
}