畅通工程
HDU 1863
模板题
要判断是否存在最小生成树,即边数要>n-1
我的代码
用kruskal算法,如果有n-1条边如何条件,输出mst,否则输出 ?
//kruskal
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int f[maxn];
int n, m, a, b, cnt, mst;
struct node{
int u, v, w;
}e[maxn];
bool cmp(node a, node b){
return a.w < b.w;
}
int Find(int x){
if(x == f[x]) return x;
else return f[x] = Find(f[x]);
}
int Union(int a, int b){
int fa = Find(a);
int fb = Find(b);
if(fa != fb){
f[fa] = fb;
return 1;
}
return 0;
}
int kruskal(){
mst = 0;
for(int i = 1; i <= m; i++){
if(Union(e[i].u, e[i].v)){
cnt++;
mst += e[i].w;
}
if(cnt == n-1) return 1;
}
return 0;
}
int main(){
while(cin >> m >> n){
if(m == 0) return 0;
for(int i = 1; i <= n; i++)
f[i] = i;
cnt = 0;
for(int i = 1; i <= m; i++){
cin >> e[i].u >> e[i].v >> e[i].w;
}
sort(e+1, e+1+m, cmp);
if(kruskal()) cout << mst << endl;
else cout << "?" << endl;
}
}
//prim
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn = 105;
int e[maxn][maxn], vis[maxn], dis[maxn];
int n, m, u, v, w, mst, cnt;
void prim(){
for(int i = 1; i <= n; i++){
int u = -1, minn = inf;
for(int j = 1; j <= n; j++){
if(!vis[j] && dis[j] < minn){
minn = dis[j];
u = j;
}
}
if(u == -1) return;
vis[u] = 1;
for(int v = 1; v <= n; v++){
if(!vis[v] && dis[v] > e[u][v]){
dis[v] = e[u][v];
}
}
}
mst = 0;
for(int i = 1; i <= n; i++)
mst += dis[i];
}
void init(){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++)
if(i == j) e[i][j] = 0;
else e[i][j] = inf;
}
for(int i = 1; i <= n; i++)
vis[i] = 0;
}
int main(){
while(cin >> m >> n){
if(m == 0) return 0;
init();
for(int i = 1; i <= m; i++){
cin >> u >> v >> w;
e[u][v] = w;
e[v][u] = w;
}
cnt = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j < i; j++){
if(e[i][j] != inf) cnt++;
}
if(cnt < n-1){cout << "?" << endl; continue; }
for(int i = 1; i <= n; i++)
dis[i] = e[1][i];
prim();
cout << mst << endl;
}
}
该博客介绍了如何运用Kruskal和Prim算法来判断图中是否存在最小生成树。通过实例展示了两种算法的实现过程,分别用C++编写了Kruskal和Prim算法的代码,并在不同情况下输出相应结果。文章强调了当边的数量大于节点数量减一时,存在最小生成树。
335

被折叠的 条评论
为什么被折叠?



