Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3230    Accepted Submission(s): 1082

      本题是简单的最小生成树问题,题意是说用最少的花费让他们全部连接起来,运用kruskals算法就能轻松搞定,因为连通两个分支,则这条线一定存在于最小生成树中

代码:

 

1 #include<stdio.h>
2 #include<queue>
3  using namespace std;
4  int father[105],rank[105];
5 typedef struct node
6 {
7 int x,y;
8 int s;
9 bool operator<(const node &a)const
10 {
11 return a.s<s;
12 }
13 }NODE;
14 int find(int x)
15 {
16 if(x!=father[x])
17 {
18 father[x]=find(father[x]);
19 }
20 return father[x];
21 }
22 void Union(int x,int y)
23 {
24 if(x==y)
25 return ;
26 if(rank[x]>rank[y])
27 {
28 father[y]=x;
29 }
30 else
31 {
32 if(rank[x]==rank[y])
33 rank[y]++;
34 father[x]=y;
35 }
36 }
37 int main()
38 {
39 priority_queue<NODE> qu;
40 NODE cur;
41 int n,i,j,q,a,b,x,y,s;
42 while(scanf("%d",&n)!=EOF)
43 {
44 while(!qu.empty ())
45 qu.pop();
46 s=0;
47 for(i=1;i<=n;i++)
48 {
49 father[i]=i;
50 rank[i]=0;
51 for(j=1;j<=n;j++)
52 {
53 scanf("%d",&a);
54 if(i!=j)
55 {
56 cur.x=i;
57 cur.y=j;
58 cur.s=a;
59 qu.push(cur);
60 }
61 }
62 }
63 scanf("%d",&q);
64 for(i=1;i<=q;i++)
65 {
66 scanf("%d%d",&a,&b);
67 x=find(a);
68 y=find(b);
69 Union(x,y);
70 }
71 while(!qu.empty ())
72 {
73 cur=qu.top();
74 qu.pop();
75 x=cur.x;
76 y=cur.y;
77 if(find(x)!=find(y))
78 {
79 s+=cur.s;
80 Union(find(x),find(y));
81 }
82 }
83 printf("%d\n",s);
84 }
85 return 0;
86 }
87
88
89
90
91
92