NYOJ 38
View Code
1 /*
2 问题描述:给定一个图求最小生成树
3 思路: K r u s k a l算法每次选择n- 1条边,
4 所使用的贪婪准则是:
5 从剩下的边中选择一条不会产生环路的具有
6 最小耗费的边加入已选择的边的集合中。
7 注意到所选取的边若产生环路则不可能形成一棵生成树。
8 K r u s k a l算法分e 步,其中e 是网络中边的数目。
9 按耗费递增的顺序来考虑这e 条边,每次考虑一条边。
10 当考虑某条边时,若将其加入到已选边的集合中会出现环路,
11 则将其抛弃,否则,将它选入。
12 利用并查集的求法判断是否会构成回路:若他们根节点不同则不会有环
13 */
14 #include<iostream>
15 #include<algorithm>
16 using namespace std;
17
18 struct node
19 {
20 int x;
21 int y;
22 int va;
23 }E[125000];
24 int sum;//总造价
25 int fa[510];
26 int v,e;
27
28 bool cmp(node x,node y)
29 {
30 return x.va<y.va;
31 }
32 int find(int x)
33 {
34 int k=x;
35 while(k!=fa[k])
36 k=fa[k];//k为根节点
37 int i=x;
38 while(i!=k)
39 {
40 int j=fa[i];
41 fa[i]=k;
42 i=j;
43 }
44 return k;
45 }
46 void slove()
47 {
48 int i;
49 for(i=0;i<=v;++i)
50 fa[i]=i;
51 sort(E+1,E+e+1,cmp);
52 for(i=1;i<=e;++i)
53 {
54 int m=find(E[i].x);
55 int n=find(E[i].y);
56 if(m!=n)
57 {
58 sum+=E[i].va;
59 fa[m]=find(n);
60 }
61 }
62 }
63
64 int main()
65 {
66 int i,j;
67 int a,b,c,t,x;
68 cin>>t;
69 while(t--)
70 {
71 cin>>v>>e;
72 for(i=1;i<=e;++i)
73 {
74 cin>>E[i].x>>E[i].y>>E[i].va;
75 }
76 cin>>sum;
77 for(i=2;i<=v;++i)
78 {
79 cin>>x;
80 if(sum>x)sum=x;//求外链最小距离
81 }
82 slove();
83 cout<<sum<<endl;
84 }
85 system("pause");
86 return 0;
87 }
88 //注意:错误:思想漏洞
89 #include<iostream>
90 #include<algorithm>
91 #include<cstring>
92 using namespace std;
93
94 struct node
95 {
96 int x;
97 int y;
98 int va;
99 }E[250000];
100 int sum;//总造价
101 bool flag[510];
102 int v,e;
103
104 bool cmp(node x,node y)
105 {
106 return x.va<y.va;
107 }
108
109 void slove()
110 {
111 int i;
112 sort(E+1,E+e+1,cmp);
113 memset(flag,0,sizeof(flag));
114 for(i=1;i<=e;++i)
115 {
116 if(!flag[E[i].x]||!flag[E[i].y]) //错在 若(1,2)加入,(3,4)加入
117 { // 则四个数flag[]都不为零,则
118 sum+=E[i].va; //(2,3)这类边即使最短也加不进去了
119 flag[E[i].x]=1;
120 flag[E[i].y]=1;
121 }
122 }
123 }
124
125 int main()
126 {
127 int i,j;
128 int a,b,c,t,x;
129 cin>>t;
130 while(t--)
131 {
132 cin>>v>>e;
133 for(i=1;i<=e;++i)
134 {
135 cin>>E[i].x>>E[i].y>>E[i].va;
136 }
137 cin>>sum;
138 for(i=2;i<=v;++i)
139 {
140 cin>>x;
141 if(sum>x)sum=x;//求外链最小距离
142 }
143 slove();
144 cout<<sum<<endl;
145 }
146 system("pause");
147 return 0;
148 }