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
原文地址:https://www.cnblogs.com/chujian123/p/3376598.html