Highways POJ

来源:互联网 发布:优惠券由来 知乎 编辑:程序博客网 时间:2024/05/18 14:24
/**理解:似曾相识的一道题,不过是它需要输出连接最短边的节点坐标而已,直接进行路径输出就可以了;开始的时候本来想去找到它的所有的坐标,然后再一并进行输出,后来发现那个数据有点难标记,就没有去搞了,后来又想了一个过程输出的思想虽然结果和所给的样例不符合,千方百计的想去啊换一下顺序,后来试了试,尴尬的过了 很兴奋,下意识的知道了它的这个输出的顺序是没有要求的;那么这个题呢解法还是prim 算法,数据量比较小,克鲁斯卡尔待跟进;具体细节 已经在代码内Mark;*/#include<cstdio>#include<cmath>#include<iostream>#include<algorithm>using namespace std;const int maxn=1e3+7;const double inf=0x3f3f3f3f*1.0;int m,n;double mmp[maxn][maxn],dis[maxn];bool vis[maxn];struct node{    double x,y;    int pos;}edge[maxn];double far(node a,node b){    double x=a.x-b.x;    double y=a.y-b.y;    return sqrt(x*x+y*y);}void build_map(){    for(int i=1;i<n;i++)        for(int j=i+1;j<=n;j++)            mmp[i][j]=mmp[j][i]=far(edge[i],edge[j]);}void prim(){    for(int i=1;i<=n;i++)    {        vis[i]=false;        dis[i]=mmp[1][i];    }    vis[1]=true;    dis[1]=0;    for(int i=1;i<=n;i++)    {        int k=-1;        double Min=inf;        for(int j=1;j<=n;j++)        {            if(!vis[j]&&dis[j]<Min)            {                Min=dis[j];                k=j;            }        }         /**        还是好好看一下这个输出吧,最多的输出的个数为n-1;        因为我们在上面就已经找到了最短的那条边;        所以呢,我们主要是判断一下开始有没有在里面即可;        */        if(k!=-1&&Min!=0) printf("%d %d\n",edge[k].pos,k);        vis[k]=true;        for(int j=1;j<=n;j++)            if(!vis[j]&&mmp[k][j]<dis[j])            {                dis[j]=mmp[k][j];                edge[j].pos=k;            }    }}int main (){    scanf("%d",&n);    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)        if(i==j) mmp[i][j]=0;    else mmp[i][j]=inf;    for(int i=1;i<=n;i++)        scanf("%lf %lf",&edge[i].x,&edge[i].y);        build_map();        int Q;        scanf("%d",&Q);///已经存在的道路无需再修,所以mmp默认为0;        for(int i=1;i<=Q;i++)        {            int u,v;            scanf("%d %d",&u,&v);            mmp[u][v]=mmp[v][u]=0;        }        prim();    return 0;}