还是畅通工程
HDU - 1233某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
当N为0时,输入结束,该用例不被处理。
Output对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3 1 2 1 1 3 2 2 3 4 4 1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5 0Sample Output
3
5
Huge input, scanf is recommended.
kruskal解决
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int pre[101];
int sum;
int n;
struct lu
{
int from;
int to;
int len;
}mp[10000];
bool cmp(lu x, lu y)
{
return x.len < y.len;
}
void init()
{
sum = 0;
memset(mp,0,sizeof(mp));
for(int i = 1; i <= 100; i++)
pre[i] = i;
}
int Find(int x)
{
int r = x;
while(r != pre[r])
{
r = pre[r];
}
int i, j = x;
while(pre[j] != r)
{
i = pre[j];
pre[j] = r;
j = i;
}
return r;
}
void Union(int p1, int p2, int w)
{
int a = Find(p1);
int b = Find(p2);
if(a != b)
{
pre[a] = b;
sum += w;
}
}
void kruskal()
{
sort(mp + 1, mp + (n-1)*n/2 + 1,cmp);
for(int i = 1; i <= (n-1)*n/2; i ++)
{
Union(mp[i].from,mp[i].to,mp[i].len);
}
}
int main()
{
while(scanf("%d", &n)!=EOF)
{
if(!n)
break;
init();
for(int i = 1; i <= n*(n - 1)/2; i ++)
{
scanf("%d %d %d", &mp[i].from, &mp[i].to, &mp[i].len);
}
kruskal();
printf("%d\n", sum);
}
return 0;
}
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; int used[105]; int head[105]; int sum; int n; int cnt; struct picture { int u; int v; int w; int next; friend bool operator < (const picture &a, const picture &b){ return a.w > b.w;} }edge[10000]; priority_queue<picture> q; void init() { memset(used, 0, sizeof(used)); memset(head, -1, sizeof(head)); cnt = 0; sum = 0; } void add(int u, int v, int w) { edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt ++; } void prim(int x, int node) { int addnod = 1; for(;addnod < node;) { used[x] = 1; for(int i = head[x]; ~i; i = edge[i].next) { if(used[edge[i].v]) continue; q.push(edge[i]); } while(!q.empty()) { picture t = q.top(); q.pop(); if(!used[t.v]) { sum += t.w; addnod ++; x = t.v; break; } } } while(!q.empty()) q.pop(); } int main() { while(scanf("%d", &n)!=EOF) { if(!n) break; init(); for(int i = 1; i <= n*(n - 1)/2; i ++) { int u, v, w; scanf("%d %d %d", &u, &v, &w); add(u, v, w); add(v, u,w);//和vector存图一致,用双边 } prim(1,n); printf("%d\n", sum); } return 0; }