poj 2253 -- Frogger (并查集+贪心)

给出石头的坐标,求从起始到终点路途中每步最短距离(注意不是总距离最短)

只需枚举每两个石头间距离,排序,从小到大依此加入图中,直到起始和终点在同一个集合中即可,证明略

#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstdio>
using namespace std;
struct Coor
{
    int x,y;
} coor[201];
struct Edge
{
    int u,v,w;
} edge[50000];
int pre[201];
int find(int x)
{
    if(pre[x]!=x)
        pre[x]=find(pre[x]);
    return pre[x];
}
void Union(int x,int y)       
{
    pre[find(x)]=find(y);
}
int cmp(const void* p1,const void* p2)   
{
    return ((Edge*)p1)->w-((Edge* )p2)->w;
}
int main()
{
    int cnt,scena=0;
    while(cin>>cnt,cnt)
    {
        for(int i=0;i<201;pre[i++]=i);
        for(int i=1;i<=cnt;cin>>coor[i].x>>coor[i].y,i++);
        int num=0;
        for(int i=1;i<=cnt;i++)
        for(int j=i+1;j<=cnt;j++)
        {
            edge[num].u=i;
            edge[num].v=j;
            edge[num].w=(coor[i].x-coor[j].x)*(coor[i].x-coor[j].x)+(coor[i].y-coor[j].y)*(coor[i].y-coor[j].y);
            num++;
        }
        qsort(edge,num,sizeof(Edge),cmp);
        int i=0;
        for(i=0;i<num;i++)
        {
            Union(edge[i].u,edge[i].v);
            if(find(1)==find(2))
            break;
        }
        double ans=sqrt(edge[i].w);
        printf("Scenario #%d\nFrog Distance = %.3f\n\n",++scena,ans);
    }
}


你可能感兴趣的:(poj 2253 -- Frogger (并查集+贪心))