标签:
一般来说能用prim算法解决的用kruscal算法也能解决问题,所以为了锻炼自己,能用的都用两种方法解决;
1.prim
用prim也是简单的套模板,就是多了一步计算两点间距离,将距离不满足题意的两点的距离设为无穷大.没有什么难度;
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <math.h> 5 using namespace std; 6 const double INF=0x3f3f3f3f*1.0; 7 struct node 8 { 9 int x; 10 int y; 11 }; 12 13 double d[105][105]; 14 int c;//岛屿个数 15 void prim() 16 { 17 double sum=0,lowcast[105]={0}; 18 int count=1; 19 for(int i=0;i<c;i++) 20 { 21 lowcast[i] = d[0][i]; 22 } 23 for(int i=0;i<c-1;i++) 24 { 25 double min = INF; 26 int k = 105; 27 for(int j=0;j<c;j++) 28 if(min>lowcast[j]&&lowcast[j]) 29 { 30 min = lowcast[j]; 31 k = j; 32 } 33 if(k!=105) 34 { 35 sum+=lowcast[k]; 36 lowcast[k]=0; 37 count++; 38 } 39 for(int j=0;j<c;j++) 40 if(d[j][k]<lowcast[j]) 41 { 42 lowcast[j] = d[j][k]; 43 } 44 } 45 if(count==c) 46 printf("%.1lf\n",sum*100); 47 else 48 printf("oh!\n"); 49 } 50 int main() 51 { 52 53 int t; 54 cin>>t; 55 while(t--) 56 { 57 node n[105]; 58 cin>>c; 59 for(int i=0;i<c;i++) 60 cin>>n[i].x>>n[i].y; 61 for(int i=0;i<c;i++) 62 for(int j=0;j<c;j++) 63 { 64 if(i==j) 65 { 66 d[i][j]=0; 67 continue; 68 } 69 70 int x1=n[i].x, x2=n[j].x; 71 int y1=n[i].y, y2=n[j].y; 72 double dist=sqrt(1.0*(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 73 if(dist<10.0||dist>1000.0)//无法建桥 74 d[j][i]=d[i][j]=INF; 75 else 76 d[j][i]=d[i][j]=dist; 77 } 78 prim(); 79 } 80 return 0; 81 }
2.kruscal
这题用kruscal也是简单的模板,与prim一样,都需要做一个两点间距离的预处理.
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 #define maxn 105 7 #define INF 0x3f3f3f3f*1.0 8 int father[maxn]; 9 int n,T; 10 struct point{ 11 int x,y; 12 }coor[maxn]; 13 struct node{ 14 int u , v; 15 double w; 16 }edge[maxn*60]; 17 void init() 18 { 19 for(int i = 0 ;i <= n ;i++) 20 father[i] = i; 21 } 22 int find(int x) 23 { 24 if(father[x]==x) 25 return x; 26 return father[x]=find(father[x]); 27 } 28 void unite(int x,int y) 29 { 30 int fx = find(x) , fy = find(y); 31 if(fx == fy) 32 return ; 33 father[fy] = fx; 34 } 35 bool cmp(node a , node b) 36 { 37 return a.w < b.w; 38 } 39 double kruscal(int t) 40 { 41 int count = 0; 42 double res = 0; 43 int u,v; 44 for(int i = 0 ;i < t; i++) 45 { 46 u = edge[i].u; 47 v = edge[i].v; 48 //if(count == n) 没加 327MS,加了514MS; 49 //return res; 50 if(find(u)!=find(v)) 51 { 52 unite(u,v); 53 count++; 54 res += edge[i].w; 55 56 } 57 58 } 59 return res; 60 } 61 int main() 62 { 63 //freopen("hdu 1233.txt","r",stdin); 64 double dis; 65 int t, x,y ; 66 scanf("%d",&T); 67 while(T--) 68 { 69 scanf("%d",&n); 70 init(); 71 t= 0; 72 for(int i = 0 ;i < n ; i++) 73 { 74 scanf("%d %d",&x,&y); 75 coor[i].x = x; 76 coor[i].y = y; 77 for(int j = 0 ; j <=i ;j++) 78 { 79 dis = sqrt((double)(coor[i].x - coor[j].x)*(coor[i].x-coor[j].x)+(double)(coor[i].y - coor[j].y)*(coor[i].y-coor[j].y)); 80 if(dis < 10 || dis > 1000) 81 continue; 82 edge[t].u = i; 83 edge[t].v = j; 84 edge[t++].w = dis; 85 // cout<<dis<<" "; 86 } 87 } 88 sort(edge,edge+t,cmp); 89 double ans = kruscal(t); 90 if(ans > 0){ 91 printf("%.1lf\n",ans*100); 92 }else 93 { 94 printf("oh!\n"); 95 } 96 } 97 return 0; 98 }
标签:
原文地址:http://www.cnblogs.com/xiaoniuniu/p/4392483.html