zoukankan      html  css  js  c++  java
  • Highways

    poj1751:http://poj.org/problem?id=1751

    题意:给你n个城市,每个城市的坐标给你,然后为了是每个城市都连通,需要在已经建了一些街道额基础上,再次建一些街道使其连通,求使得所建街道最短的那些边。
    题解:直接求一棵生成树,把已经建好的边的边权设置为0,用prim走一遍。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define INF 100000000.0
     7 using namespace std;
     8 struct Node{
     9     int x;
    10     int y;
    11 }node[800];//储存村庄 
    12 double g[800][800];
    13 double lowcost[800];
    14 bool flag;
    15 double juli(Node a,Node b){//求距离 ,注意数据类型 
    16     double xx=pow(((double)a.x-b.x),2);
    17     double yy=pow(((double)a.y-b.y),2);
    18     return sqrt(xx+yy);
    19 }
    20 int n,m,nearvex[800],u,v1;
    21 void prim(int v0){
    22     flag=false;//标记是否需要建边 
    23     for(int i=1;i<=n;i++){
    24         lowcost[i]=g[v0][i];
    25         nearvex[i]=v0;
    26     }
    27     nearvex[v0]=-1;
    28     for(int i=1;i<n;i++){
    29         double min=INF;//注意这里的数据类型,不能换成int 
    30         int v=-1;
    31         for(int j=1;j<=n;j++){
    32             if(nearvex[j]!=-1&&lowcost[j]<min){
    33                 v=j;
    34                 min=lowcost[j];
    35             }
    36         }
    37         if(v!=-1){
    38             if(lowcost[v]!=0){
    39                 flag=true;
    40                 printf("%d %d
    ",nearvex[v],v);//找到就输出 
    41             }
    42             nearvex[v]=-1;
    43             for(int k=1;k<=n;k++){
    44                 if(nearvex[k]!=-1&&g[v][k]<lowcost[k]){
    45                     nearvex[k]=v;
    46                     lowcost[k]=g[v][k];
    47                 }
    48             }
    49         }
    50     }
    51   if(!flag)printf("
    ");//没有要建的边,就输出空行    
    52 }
    53 int main(){
    54     while(~scanf("%d",&n)){
    55        for(int i=1;i<=n;i++)//存点 
    56           scanf("%d%d",&node[i].x,&node[i].y);
    57        for(int i=1;i<=n;i++)//建图 
    58           for(int j=i+1;j<=n;j++){
    59               g[i][j]=g[j][i]=juli(node[i],node[j]);
    60           }
    61         for(int i=1;i<=n;i++)//初始化 
    62          for(int j=1;j<=n;j++){
    63              if(i==j)g[i][j]=0;
    64              else if(g[i][j]==0)g[i][j]=INF;
    65          }  
    66         scanf("%d",&m);
    67         for(int i=1;i<=m;i++){//处理已经不需要建的边 
    68             scanf("%d%d",&u,&v1);
    69             g[u][v1]=g[v1][u]=0;
    70         }
    71         prim(1);  
    72           
    73     }
    74 }
    View Code
  • 相关阅读:
    GL_TRIANGLE_FAN Vs GL_TRIANGLE_STRIP
    Color bleeding与caustics概念解析
    Two path ray tracing与Photon Mapping(粒子跟踪)
    右手定则判断法线方向
    正确使用atoi
    深入探讨透视投影坐标变换
    gluBuild2DMipmaps与glTexImage2D与glGenTexture()函数
    OpenGL纹理贴图流程
    int main( int argc, char ** argv)在VS2008中的配置的一个实例
    c++标准库中vector数组遍历时的用法
  • 原文地址:https://www.cnblogs.com/chujian123/p/3376598.html
Copyright © 2011-2022 走看看