Source : hdu 1233 还是畅通工程
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
裸的MST,不说了,参考我之前的文章(介绍MST)
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
0
Sample Output
3
5
方法一:prim+图的邻接矩阵存储
方法二:Kruskal+图的邻接表存储
#include<bits/stdc++.h>
#define clr(k,v) memset(k,v,sizeof(k))
#define INF 0x3f3f3f3f
using namespace std;
const int _max = 100 + 10;
bool vis[_max];
int a,b,n,temp,low[_max],cost[_max][_max];//邻接矩阵
int prim(){//普利姆算法求解MST
int ans = 0;
clr(vis,0);
int pos = 1;
vis[1] = true;
for(int i = 1; i <= n; ++ i) low[i] = (i == 1?0:cost[1][i]);
for(int i = 1; i < n; ++ i){//循环n-1次,每次循环加入一个点
int min = INF;
for(int j = 1;j <= n; ++ j)
if(vis[j] == false && low[j] < min){
min = low[j];
pos = j;
}
if(min == INF) return -1;//原图不连通
ans += min;
vis[pos] = true;
for(int j = 1; j <= n; ++ j)
if(vis[j] == false && cost[pos][j] < low[j]){
low[j] = cost[pos][j];
}
}
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d",&n) == 1 && n){
clr(cost,0);
for(int i = 0; i < n*(n-1)/2; ++ i){
scanf("%d%d%d",&a,&b,&temp);
cost[b][a] = cost[a][b] = temp;//无向图是转置的
}
printf("%d\n",prim());
}
return 0;
}
#include<bits/stdc++.h>
#define clr(k,v) memset(k,v,sizeof(k))
#define INF 0x3f3f3f3f
using namespace std;
const int _max = 100 + 10;
int u,v,w,n;
int F[_max];//并查集使用
struct Edge{
int u,v,w;
}edge[_max*_max];//最大边数,存储边的信息,包括起点/终点/权值
int tol;//边数,加边前赋值为0
void addedge(int u,int v,int w){
edge[tol].u = u;
edge[tol].v = v;
edge[tol++].w = w;
}
//排序函数,将边按照权值从小到大排序
bool cmp(Edge a,Edge b){
return a.w < b.w;
}
int find(int x){//并查集的查操作,带路径压缩
if(F[x] == -1) return x;
return F[x] = find(F[x]);
}
//返回最小生成树的权值,如果不连通返回-1
int Kruskal(){
clr(F,-1);
sort(edge,edge+tol,cmp);
int cnt = 0;
int ans = 0;
for(int i = 0; i < tol; ++ i){
int u = edge[i].u;
int v = edge[i].v;
int w = edge[i].w;
int t1 = find(u);
int t2 = find(v);
if(t1 != t2){
ans += w;
F[t1] = t2;
cnt++;
}
if(cnt == n - 1) break;
}
if(cnt < n - 1) return -1;
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d",&n) == 1 && n){
tol = 0;
for(int i = 0; i < n*(n-1)/2; ++ i){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
printf("%d\n",Kruskal());
}
return 0;
}
Ctrl + B
Ctrl + I
Ctrl + Q
Ctrl + L
Ctrl + K
Ctrl + G
Ctrl + H
Ctrl + O
Ctrl + U
Ctrl + R
Ctrl + Z
Ctrl + Y
版权声明:本文为博主原创文章,未经博主允许不得转载。
【裸MST:prim+邻接矩阵 / Kruskal+邻接表】hdu 1233 还是畅通工程
原文地址:http://blog.csdn.net/u012717411/article/details/48065183