畅通工程再续Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 37053 Accepted Submission(s): 12398 Problem Description 相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
Input 输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。
Output 每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.
Sample Input 2 2 10 10 20 20 3 1 1 2 2 1000 1000
Sample Output 1414.2 oh!
Author 8600
Source |
Prime算法:
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<cstring>
using namespace std;
const int MAX=2000+10;
const double INF=100000007.0;
struct point{
double x;
double y;
};
double diss(point a,point b){
return sqrt((a.x -b.x)*(a.x -b.x)+(a.y -b.y)*(a.y -b.y));
}
double Map[MAX][MAX];
double Prim(int from,int to,int n){
double dis[MAX];
bool vis[MAX];
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++)
dis[i]=Map[1][i];
vis[from]=true;
double sum=0.0,Min;
int f;
for(int i=1;i<=n-1;i++){
Min=INF;
for(int k=1;k<=n;k++){
if(!vis[k] && dis[k]<Min)
Min=dis[k],f=k;
}
if(Min==INF) return INF;
vis[f]=true;
sum+=dis[f];
for(int k=1;k<=n;k++){
if(!vis[k]&&Map[f][k]<dis[k])
dis[k]=Map[f][k];
}
}
return sum;
}
int main(){
int n,t;
cin>>t;
while(t--){
cin>>n;
point p[1200];
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j)
Map[i][j]=0.0;
else
Map[i][j]=INF;
}
}
for(int i=1;i<=n;i++){
cin>>p[i].x>>p[i].y;
}
for(int i=1;i<=n-1;i++){
for(int j=i+1;j<=n;j++){
double temp=diss(p[i],p[j]);
if(temp<10.0||temp>1000.0)
Map[i][j]=Map[j][i]=INF;
else
Map[i][j]=Map[j][i]=temp;
}
}
double ans=Prim(1,n,n);
if(ans==INF) cout<<"oh!"<<endl;
else{
printf("%.1lf\n",ans*100.0);
}
}
return 0;
}
再来个看起来清爽一点的版本:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAX_N=2050;
const double INF=100000007.0;
struct point{
double x;
double y;
};
double dist(point a,point b){
return sqrt((a.x -b.x)*(a.x -b.x)+(a.y -b.y)*(a.y -b.y));
}
double mincost[MAX_N];
bool used[MAX_N];
double cost[MAX_N][MAX_N];
int V;
double Prim(){
for(int i=1;i<=V;i++){
mincost[i]=cost[1][i]; //初始化的时候注意一下方式,这个不能直接全部INF
used[i]=false;
}
mincost[0]=0.0;
double res=0.0;
while(true){
int v=-1;
for(int u=1;u<=V;u++){
if(!used[u] && (v == -1||mincost[u]<mincost[v]))
v=u;
}
if(v==-1) break;
used[v]=true;
res+=mincost[v];
for(int u=1;u<=V;u++){
mincost[u]=min(mincost[u],cost[v][u]);
}
}
return res;
}
int main(){
int t;
cin>>t;
while(t--){
cin>>V;
point p[1200];
for(int i=1;i<=V;i++){
for(int j=1;j<=V;j++){
cost[i][j]=(i==j? 0.0:INF);
}
}
for(int i=1;i<=V;i++){
cin>>p[i].x>>p[i].y;
}
for(int i=1;i<=V-1;i++){
for(int j=i+1;j<=V;j++){
double temp=dist(p[i],p[j]);
cost[i][j]=cost[j][i]=((temp<10.0||temp>1000.0)? INF:temp);
}
}
double ans=Prim();
if(ans>=INF)cout<<"oh!"<<endl;
else
printf("%.1lf\n",ans*100);
}
return 0;
}