最小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上 就得到了 ...
随机推荐
- Kubernetes-设计理念(三)
Kubernetes设计理念与分布式系统 分析和理解Kubernetes的设计理念可以使我们更深入的了解Kubernetes系统,更好的利用它管理分布式部署的云原生应用,另一方面也可以让我们借鉴其在分 ...
- BZOJ:2038: [2009国家集训队]小Z的袜子(hose)(莫队算法模板)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 解题心得: 第一次接触莫队算法,很神奇,很巧妙.莫队算法主要就是用来解决多次询问时 ...
- Java输出日历写法
package TestString_2; import java.text.ParseException;import java.util.Calendar;import java.util.Gre ...
- Python正则反向引用
str2 ="2018-10-29"c =re.sub(r"(\d{4})-(\d{2})-(\d{2})","\g<1>/\g<2 ...
- 在Linux上进行mySql安装部署及遇到的问题的解决方法
前提: Linux centOS虚拟机64位 1.首先确认是否已安装过MySQL 方法一:删除原有的MySQL目录: 使用查找语句: whereis mysql find / -name mysql ...
- Java 集合学习--集合概述
一.集合框架 集合,通常也叫容器,java中有多种方式保存对象,集合是java保存对象(对象的引用)的方式之一,之前学习的数组是保存对象的最有效的方式,但是数组却存在一个缺陷,数组的大小是固定的,但是 ...
- Linux开发C语言规范
-Iinclude:找头文件目录 ,获取头文件的目录 -C:创建.o文件 .h:文件用来声明函数,即写一个函数名. 如 int add(); int div(); int mul(); .c:文件定义 ...
- 机器学习 (二) 多变量线性回归 Linear Regression with Multiple Variables
文章内容均来自斯坦福大学的Andrew Ng教授讲解的Machine Learning课程,本文是针对该课程的个人学习笔记,如有疏漏,请以原课程所讲述内容为准.感谢博主Rachel Zhang 的个人 ...
- for循环再探
摘要:for循环头的组成.for的执行流程 一.for 语句的组成 0. 举个例子 for (int val = 1; val <= 10; ++val) sum += val; 1. 循环头的 ...
- url解析字符串
课程链接:http://www.imooc.com/video/6711/0