最大度限制生成树
我就是来抄模板的=_=
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <map>
#define maxn 52
using namespace std;
const int inf = 0x7fffffff / 3;
string s;
map<string, int>M;
int n, cnt;
int Min[maxn], idx[maxn], f[maxn][maxn];
bool vis[maxn][maxn];
struct Edge{
int u, v, w;
}c[maxn * maxn], dp[maxn];
bool cmp(const Edge& i, const Edge& j){
return i.w < j.w;
}
int fa[maxn];
int ufs(int x){return x == fa[x] ? x : fa[x] = ufs(fa[x]);}
int Kruscal(){
int ans = 0;
sort(c + 1, c + 1 + n, cmp);
for(int i = 1; i <= 50; i ++)
fa[i] = i;
for(int i = 1; i <= n; i ++){
if(c[i].u == 1 || c[i].v == 1)
continue;
int u = ufs(c[i].u), v = ufs(c[i].v);
if(u != v){
fa[u] = v;
ans += c[i].w;
vis[c[i].u][c[i].v] = vis[c[i].v][c[i].u] = true;
}
}return ans;
}
void DFS(int x, int fa){
for(int i = 2; i <= cnt; i ++){
if(i != fa && vis[x][i]){
if(dp[i].w == -1){
if(dp[x].w > f[x][i])
dp[i] = dp[x];
else{
dp[i].w = f[x][i];
dp[i].u = x;
dp[i].v = i;
}
}DFS(i, x);
}
}
}
int main(){
scanf("%d", &n);
cnt = M["Park"] = 1;
int u, v, w;
memset(f, -1, sizeof f);
for(int i = 1; i <= n; i ++){
cin >> s;
if(!M[s])M[s] = ++ cnt;
u = M[s];
cin >> s;
if(!M[s])M[s] = ++ cnt;
v = M[s];
scanf("%d", &w);
c[i].u = u, c[i].v = v, c[i].w = w;
if(f[u][v] == -1)
f[u][v] = f[v][u] = w;
else f[u][v] = f[v][u] = min(f[u][v], w);
}
int k;
scanf("%d", &k);
for(int i = 1; i <= 50; i ++)
Min[i] = inf;
int ans = Kruscal();
for(int i = 2; i <= cnt; i ++){
if(f[1][i] != -1){
int x = ufs(i);
if(Min[x] > f[1][i]){
Min[x] = f[1][i];
idx[x] = i;
}
}
}
int m = 0;
for(int i = 1; i <= cnt; i ++){
if(Min[i] != inf){
m ++;
vis[1][idx[i]] = vis[idx[i]][1] = true;
ans += f[1][idx[i]];
}
}
for(int i = m + 1; i <= k; i ++){
memset(dp, -1, sizeof dp);
dp[1].w = -inf;
for(int j = 2; j <= cnt; j ++)
if(vis[1][j])
dp[j].w = -inf;
DFS(1, -1);
int tmp, mn = inf;
for(int j = 2; j <= cnt; j ++){
if(f[1][j] != -1){
if(mn > f[1][j] - dp[j].w){
mn = f[1][j] - dp[j].w;
tmp = j;
}
}
}
if(mn >= 0)break;
int x = dp[tmp].u, y = dp[tmp].v;
vis[x][y] = vis[y][x] = false;
vis[1][tmp] = vis[tmp][1] = true;
ans += mn;
}
printf("Total miles driven: %d\n", ans);
return 0;
}