Constructing Roads (最小生成树)
HDU - 1102
模板题
我的代码
prim算法
有几条路事先修好了,那么把修好路的两个点看成同一个点,即两点间距离为0即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
#define inf 0x3f3f3f3f
int n, a, b, x, q;
int e[maxn][maxn], vis[maxn], dis[maxn];
int mst;
void init(){
for(int i = 1; i <= n; i++)
vis[i] = 0;
mst = 0;
}
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];
}
return;
}
int main(){
while(cin >> n){
init();
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
cin >> e[i][j];
}
}
cin >> q;
for(int i = 1; i <= q; i++){
cin >> a >> b;
e[a][b] = 0;
e[b][a] = 0;
}
for(int i = 1; i <= n; i++)
dis[i] = e[1][i];
prim();
cout << mst << endl;
}
}
kruskal算法
有几条路事先修好了,那么把修好路的两个点看成同一个点,即两个点为同一个集合
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
int n, q, a, b, x;
int f[maxn], mst, cnt;
struct node{
int u, v, w;
bool operator < (node k) const{return w < k.w;}
}e[10005];
bool cmp(node a, node b){
return a.w < b.w;
}
int Find(int x){
if(f[x] == 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 main(){
while(cin >> n){
for(int i = 1; i <= n; i++)
f[i] = i;
cnt = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
cin >> x;
if(j > i){
e[cnt].u = i;
e[cnt].v = j;
e[cnt].w = x;
cnt++;
}
}
}
sort(e, e+cnt);
cin >> q;
for(int i = 1; i <= q; i++){
cin >> a >> b;
Union(a, b);
}
//kruskal:
mst = 0;
for(int i = 0; i < cnt; i++){
if(Union(e[i].u, e[i].v))
mst += e[i].w;
}
cout << mst << endl;
}
}