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 }