基本上是裸的最小生成树。。
prim算法
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define eps 1e-8
#define ll long long
#define ull unsinged long long
#define inf 0x3f3f3f3f
#define mnx 1005
int dis[mnx], g[mnx][mnx], ans;
void prim(int n){
memset(dis, 0x3f, sizeof(dis));
int now, min_edge, min_node;
now = 1;
ans = 0;
for( int i = 1; i < n; i++ ){
dis[now] = -1;
min_edge = inf;
for( int j = 1; j <= n; j++ ){
if( dis[j] >= 0 && j != now ){
dis[j] = min(dis[j], g[now][j]); //更新j结点的最短边
if( dis[j] < min_edge ){
min_edge = dis[j];
min_node = j;
}
}
}
now = min_node;
ans += min_edge;
}
}
int main(){
int n, m;
while( scanf("%d", &n) != EOF && n){
m = (n-1) * n / 2;
int u, v, c, ok;
for( int i = 0; i < m; i++ ){
scanf("%d%d%d%d", &u, &v, &c, &ok);
if( ok == 1 ){
g[u][v] = 0; g[v][u] = 0;
}
else {
g[u][v] = c; g[v][u] = c;
}
}
prim(n);
printf("%d\n", ans);
}
return 0;
}
kruska 算法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define eps 1e-8
#define ll long long
#define ull unsigned long long
#define mnx 5005
struct edge{
int u, v, c;
bool operator < (const edge &b) const {
return c < b.c;
}
}e[mnx];
int fa[mnx];
int find( int x ){
if ( x != fa[x] ){
fa[x] = find( fa[x] );
}
return fa[x];
}
int kruska( int n, int m ){
int ans = 0;
sort( e, e+m );
for( int i = 0; i <= n; i++ ) fa[i] = i; // i<=n 注意,wa了一次
for( int i = 0; i < m; i++ ){
int u = e[i].u, v = e[i].v;
if( find(u) == find(v) ) continue;
ans += e[i].c;
fa[find(u)] = find(v);
}
return ans;
}
int main(){
int n, m;
while( cin>>n && n){
m = n*(n-1)/2;
int u, v, c, vis;
for( int i = 0; i < m; i++ ){
scanf("%d%d%d%d", &u, &v, &c, &vis);
e[i].u = u;
e[i].v = v;
if( vis ) e[i].c = 0;
else e[i].c = c;
}
cout<<kruska(n, m)<<endl;
}
return 0;
}