最小k度最小生成树模板
代码是抄的
题解是瞄的
可我想学习的心是真的嘤嘤嘤
然而
还是上传一份ioi大神的论文吧
链接:https://pan.baidu.com/s/1neIW9QeZEa0hXsUqJTjmeQ
密码:blr4
代码如下
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000") const int INF = 0x3f3f3f3f;
const int maxn = ; using namespace std; struct Edge{
int u, v, d;
Edge() {}
Edge(int a, int b, int c) : u(a), v(b), d(c) {}
bool operator < (const Edge &e) const {
return d < e.d;
}
}; int n, m, k;
int cnt;
int ans;
int f[maxn]; // 并查集
map<string, int> nodes;
vector<Edge> edges;
Edge dp[maxn];
int g[maxn][maxn];
bool tree[maxn][maxn]; // tree[i][j]=true表示<i, j>这条边在最小生成树中
int minEdge[maxn]; int find(int p) {
if (p == f[p]) return f[p];
return f[p] = find(f[p]);
} void unite(int p, int q) {
f[find(p)] = find(q);
} void kruskal() {
sort(edges.begin(), edges.end());
for (int i = ; i < edges.size(); i++) {
int p = edges[i].u;
int q = edges[i].v;
if (p == || q == ) continue; // 忽略根节点
if (find(p) != find(q)) {
unite(p, q);
tree[p][q] = tree[q][p] = ;
ans += edges[i].d;
}
}
} void dfs(int cur, int pre) {
for (int i = ; i <= cnt; i++) {
if (i == pre || !tree[cur][i]) continue;
if (dp[i].d == -) {
if (dp[cur].d > g[cur][i]) dp[i] = dp[cur];
else {
dp[i].u = cur;
dp[i].v = i;
dp[i].d = g[cur][i];
}
}
dfs(i, cur);
}
} void solve() {
int keyPoint[maxn];
for (int i = ; i <= cnt; i++) {
if (g[][i] != INF) {
// 点i在哪颗最小生成树中
int color = find(i);
// 每颗最小生成树中距离根节点最近的点与根节点的距离
if (minEdge[color] > g[][i]) {
minEdge[color] = g[][i];
keyPoint[color] = i;
}
}
}
for (int i = ; i <= cnt; i++) {
if (minEdge[i] != INF) {
m++;
tree[][keyPoint[i]] = tree[keyPoint[i]][] = ;
ans += g[][keyPoint[i]];
}
}
// 由i-1度生成树得i度生成树
for (int i = m + ; i <= k; i++) {
memset(dp, -, sizeof(dp));
dp[].d = -INF;
for (int j = ; j <= cnt; j++)
if (tree[][j]) dp[j].d = -INF;
dfs(, -); // dp预处理
int idx, minnum = INF;
for (int j = ; j <= cnt; j++) {
if (minnum > g[][j] - dp[j].d) {
minnum = g[][j] - dp[j].d;
idx = j;
}
}
if (minnum >= ) break;
tree[][idx] = tree[idx][] = ;
tree[dp[idx].u][dp[idx].v] = tree[dp[idx].v][dp[idx].u] = ;
ans += minnum;
}
} void init() {
memset(g, 0x3f, sizeof(g));
memset(tree, , sizeof(tree));
memset(minEdge, 0x3f, sizeof(minEdge));
m = ;
cnt = ;
ans = ;
nodes["Park"] = ;
for (int i = ; i < maxn; i++)
f[i] = i;
} int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
scanf("%d", &n);
string s1, s2;
int d;
init();
for (int i = ; i <= n; i++) {
cin >> s1 >> s2 >> d;
if (!nodes[s1]) nodes[s1] = ++cnt;
if (!nodes[s2]) nodes[s2] = ++cnt;
int u = nodes[s1], v = nodes[s2];
edges.push_back(Edge(u, v, d));
g[u][v] = g[v][u] = min(g[u][v], d);
}
scanf("%d", &k);
kruskal(); // 忽略根节点先计算一次最小生成树,此时得到一个森林
solve();
printf("Total miles driven: %d\n", ans);
return ;
}
最小k度最小生成树模板的更多相关文章
- 【POJ 1639】 Picnic Planning (最小k度限制生成树)
[题意] 有n个巨人要去Park聚会.巨人A和先到巨人B那里去,然后和巨人B一起去Park.B君是个土豪,他家的停车场很大,可以停很多车,但是Park的停车场是比较小.只能停k辆车.现在问你在这个限制 ...
- poj 1639 最小k度限制生成树
题目链接:https://vjudge.net/problem 题意: 给各位看一下题意,算法详解看下面大佬博客吧,写的很好. 参考博客:最小k度限制生成树 - chty - 博客园 https:/ ...
- 最小k度限制生成树
[题目描述] 给你一个图,n个点,m条边,求一颗生成树满足如下条件: (1)结点1的度不超过k. (2)在(1)条件下所求生成树最小. [算法引入] 最小k度限制生成树,就是指有特殊的某一点的度不能超 ...
- poj1639 Picnic Planning,K度限制生成树
题意: 矮人虽小却喜欢乘坐巨大的轿车,车大到能够装下不管多少矮人.某天,N(N≤20)个矮人打算到野外聚餐.为了集中到聚餐地点,矮人A 要么开车到矮人B 家中,留下自己的轿车在矮人B 家,然后乘坐B ...
- HDU 4862 Jump(最小K路径覆盖)
输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...
- Picnic Planning POJ - 1639(最小k度生成树)
The Contortion Brothers are a famous set of circus clowns, known worldwide for their incredible abil ...
- HDU3376 最小费用最大流 模板2
Matrix Again Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)To ...
- poj 1258 最小生成树 模板
POJ 最小生成树模板 Kruskal算法 #include<iostream> #include<algorithm> #include<stdio.h> #in ...
- K度限制MST poj 1639
/* k度限制MST:有一个点的度<=k的MST poj 1639 要求1号点的度不超过k 求MST 我们先把1号点扔掉 跑MST 假设有sum个连通分支 然后把这sum个分支连到1上 就得到了 ...
随机推荐
- ruby Dir类
类方法 1. Dir[pat] Dir::glob( pat) 返回一个数组,包含与指定的通配符模式 pat 匹配的文件名: * - 匹配包含 null 字符串的任意字符串 ** - 递归地匹配 ...
- 笨方法学python之import sys与from sys import argv的区别
这是在网上看到的一个大神的解答: sys is a module that contains “system functionality”. sys.argv is a list containing ...
- stm32+lwip(三):TCP测试
我是卓波,很高兴你来看我的博客. 系列文章: stm32+lwip(一):使用STM32CubeMX生成项目 stm32+lwip(二):UDP测试 stm32+lwip(三):TCP测试 stm32 ...
- 42-EF Core Migration
1-常用命令 1-由于2.1版本有点不一样,不会自动创建ApplicationUser类,发现合并没效果.暂时略 增加一个字段 E:\coding\netcore\IdentitySample> ...
- c/c++指针传参
首先要理解参数传递,参数传递分值传递,指针传递,引用传递.(就我自己理解,就是把实参对形参进行赋值) 值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值.从被调用函数的角度来说,值传递是单 ...
- 1 opencv2.4 + vs2013
http://blog.csdn.net/poem_qianmo/article/details/19809337 1.安装vs2013 2.安装opencv2.4 下载地址:https://sour ...
- SpringBoot学习:使用logback进行日志记录
项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)pom.xml文件中引入jar: <!-- https://mvnrepos ...
- abo dto属性验证的坑
问题回现: public class ShipmentRequestDto { public string FromPhoneNumber { get; set; } /// <summary& ...
- CF 55D
Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer numb ...
- LeetCode 410——分割数组的最大值
1. 题目 2. 解答 此题目为 今日头条 2018 AI Camp 5 月 26 日在线笔试编程题第二道--最小分割分数. class Solution { public: // 若分割数组的最大值 ...