Kruskal算法 Swordfish
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=203
A world beneath what we call cyberspace.
A world protected by firewalls,
passwords and the most advanced
security systems.
In this world we hide
our deepest secrets,
our most incriminating information,
and of course, a shole lot of money.
This is the world of Swordfish.
We all remember that
in the movie Swordfish, Gabriel broke into the World Bank Investors Group in
West Los Angeles, to rob $9.5 billion. And he needed Stanley, the best hacker in
the world, to help him break into the password protecting the bank system.
Stanley's lovely daughter Holly was seized by Gabriel, so he had to work for
him. But at the last moment, Stanley made some little trick in his hacker
mission: he injected a trojan horse in the bank system, so the money would jump
from one account to another account every 60 seconds, and would continue jumping
in the next 10 years. Only Stanley knew when and where to get the money. If
Gabriel killed Stanley, he would never get a single dollar. Stanley wanted
Gabriel to release all these hostages and he would help him to find the money
back.
You who has watched the movie know that Gabriel at last got the money
by threatening to hang Ginger to death. Why not Gabriel go get the money
himself? Because these money keep jumping, and these accounts are scattered in
different cities. In order to gather up these money Gabriel would need to build
money transfering tunnels to connect all these cities. Surely it will be really
expensive to construct such a transfering tunnel, so Gabriel wants to find out
the minimal total length of the tunnel required to connect all these cites. Now
he asks you to write a computer program to find out the minimal length. Since
Gabriel will get caught at the end of it anyway, so you can go ahead and write
the program without feeling guilty about helping a
criminal.
Input:
The input contains several test cases. Each
test case begins with a line contains only one integer N (0 <= N <=100),
which indicates the number of cities you have to connect. The next N lines each
contains two real numbers X and Y(-10000 <= X,Y <= 10000), which are the
citie's Cartesian coordinates (to make the problem simple, we can assume that we
live in a flat world). The input is terminated by a case with N=0 and you must
not print any output for this case.
Output:
You need to help
Gabriel calculate the minimal length of tunnel needed to connect all these
cites. You can saftly assume that such a tunnel can be built directly from one
city to another. For each of the input cases, the output shall consist of two
lines: the first line contains "Case #n:", where n is the case number (starting
from 1); and the next line contains "The minimal distance is: d", where d is the
minimal distance, rounded to 2 decimal places. Output a blank line between two
test cases.
Sample Input:
5 0 0 0 1 1 1 1 0 0.5 0.5 0
Sample Output:
Case #1: The minimal distance is: 2.83
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<string> 6 #include<stack> 7 #include<queue> 8 #include<set> 9 #include<map> 10 #include<vector> 11 #include<cmath> 12 using namespace std; 13 14 const int MAXN=100; 15 const int MAXM=5000; 16 struct edge 17 { 18 int u,v; 19 double w; 20 } edges[MAXM]; 21 int fa[MAXN]; 22 int n,m; 23 double X[MAXN],Y[MAXN]; 24 double sum; 25 26 void fa_set() 27 { 28 for(int i=0;i<n;i++) 29 fa[i]=-1; 30 return ; 31 } 32 33 int find(int x) 34 { 35 int s; 36 for(s=x;fa[s]>=0;s=fa[s]); 37 while(s!=x) 38 { 39 int tmp=fa[x]; 40 fa[x]=s; 41 x=tmp; 42 } 43 return s; 44 } 45 46 void make_union(int x,int y) 47 { 48 int f1=find(x); 49 int f2=find(y); 50 int tmp=fa[f1]+fa[f2]; 51 if(fa[f1]>fa[f2]) 52 { 53 fa[f1]=f2; 54 fa[f2]=tmp; 55 } 56 else 57 { 58 fa[f2]=f1; 59 fa[f1]=tmp; 60 } 61 return ; 62 } 63 /* 64 int cmp(const void *a,const void *b) 65 { 66 // return ((edge*)a)->w-((edge*)b)->w; 67 if(((edge*)a)->w>((edge *)b)->w) 68 return 1; 69 return -1; 70 }*/ 71 72 bool cmp(const edge &a,const edge &b) 73 { 74 return a.w<=b.w; 75 } 76 void kruskal() 77 { 78 int num=0; 79 int u,v; 80 fa_set(); 81 sum=0; 82 for(int i=0;i<m;i++) 83 { 84 u=edges[i].u; 85 v=edges[i].v; 86 if(find(u)!=find(v)) 87 { 88 sum+=edges[i].w; 89 num++; 90 make_union(u,v); 91 } 92 if(num>=n-1) 93 break; 94 } 95 return ; 96 } 97 98 int main() 99 { 100 double d; 101 int cas=1,i,j; 102 while(1) 103 { 104 scanf("%d",&n); 105 if(n==0) 106 break; 107 for(i=0;i<n;i++) 108 scanf("%lf%lf",&X[i],&Y[i]); 109 int mi=0; //mi=n*(n-1)/2; 110 for(i=0;i<n;i++) 111 for(j=i+1;j<n;j++) 112 { 113 d=sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j])); 114 edges[mi].u=i; 115 edges[mi].v=j; 116 edges[mi].w=d; 117 mi++; 118 } 119 m=mi; 120 //qsort(edges,m,sizeof(edges[0]),cmp); 121 sort(edges,edges+m,cmp); 122 kruskal(); 123 if(cas>1) 124 printf("\n"); 125 printf("Case #%d:\n",cas); 126 printf("The minimal distance is: %.2lf\n",sum); 127 cas++; 128 } 129 return 0; 130 }