hdu 1875 最小生成树 prime版

最小生成树prime版   

大致的步骤  

首先选取一个到集合最近的点 然后标记起在集合内部 然后更新最短距离

 

 

畅通工程再续

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24846    Accepted Submission(s): 8035


Problem Description
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
 

 

Input
输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
 

 

Output
每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.
 

 

Sample Input
2 2 10 10 20 20 3 1 1 2 2 1000 1000
 

 

Sample Output
1414.2 oh!
 
#include<cstdio>
#include<iostream>
#include<string.h>
#include<cmath>
#define maxn 105
#define inf 9999999
struct node
{
    double x,y;    
}stu[maxn];
int vis[maxn],n;//用来表示点是否在集合里 
double mincost[maxn];//用来记录从集合出来到每个点的最小距离 
double mapp[maxn][maxn];
using namespace std;
double get_len(node a,node b)
{
    return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0));
}
void build_map()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=i;j<=n;j++)
        {
            double len=get_len(stu[i],stu[j]);
            if(len>=10&&len<=1000)
            mapp[i][j]=mapp[j][i]=(i==j)?0:len;
            else mapp[i][j]=mapp[j][i]=inf;
        }
    }
}
void init()
{
    memset(vis,0,sizeof(vis));
}
double minn(double x,double y)
{
    if(x-y>0) return y;
    else return x;
}
double prim()
{
    fill(mincost,mincost+n+1,inf);
    mincost[1]=0;
    double res=0;
    while(1)
    {
        int v=-1;
        for(int i=1;i<=n;i++)    if(!vis[i]&&(v==-1||mincost[i]<mincost[v])) v=i;//找出离集合最近的点 
        if(v==-1) break;
        vis[v]=1;
        res+=mincost[v];
        for(int i=1;i<=n;i++) mincost[i]=minn(mincost[i],mapp[v][i]);//更新最小距离
    }
    return res;
}
int main()
{
    cin.sync_with_stdio(false);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lf %lf",&stu[i].x,&stu[i].y);
        build_map();
        double temp=prim()*100.0;
        if(temp>inf) printf("oh!\n");
        else printf("%.1f\n",temp);
    }
    return 0;
}

#include<cstdio>#include<iostream>#include<string.h>#include<cmath>#define maxn 105#define inf 9999999struct node{    double x,y;}stu[maxn];int vis[maxn],n;//用来表示点是否在集合里 double mincost[maxn];//用来记录从集合出来到每个点的最小距离 double mapp[maxn][maxn];using namespace std;double get_len(node a,node b){return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0));}void build_map(){for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){double len=get_len(stu[i],stu[j]);if(len>=10&&len<=1000)mapp[i][j]=mapp[j][i]=(i==j)?0:len;else mapp[i][j]=mapp[j][i]=inf;}}}void init(){memset(vis,0,sizeof(vis));}double minn(double x,double y){if(x-y>0) return y;else return x;}double prim(){fill(mincost,mincost+n+1,inf);mincost[1]=0;double res=0;    while(1)    {    int v=-1;    for(int i=1;i<=n;i++)if(!vis[i]&&(v==-1||mincost[i]<mincost[v])) v=i;//找出离集合最近的点     if(v==-1) break;    vis[v]=1;res+=mincost[v];for(int i=1;i<=n;i++) mincost[i]=minn(mincost[i],mapp[v][i]);    }    return res;}int main(){cin.sync_with_stdio(false);int t;    scanf("%d",&t);while(t--)    {    init();    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%lf %lf",&stu[i].x,&stu[i].y);        build_map();        double temp=prim()*100.0;        if(temp>inf) printf("oh!\n");        else printf("%.1f\n",temp);    }return 0;}

posted @ 2016-08-23 15:40  猪突猛进!!!  阅读(136)  评论(0编辑  收藏  举报