最小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上 就得到了 ...
随机推荐
- Leecode刷题之旅-C语言/python-53.最大子序和
/* * @lc app=leetcode.cn id=53 lang=c * * [53] 最大子序和 * * https://leetcode-cn.com/problems/maximum-su ...
- 素数环 南阳acm488(回溯法)
素数环 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环. 为了简 ...
- 算法竞赛入门经典-1.5.4 Q&A
这小节考察实践能力,要求在不要查书.不要网上找答案,自己用实验的方法解决以下五个问题: 做这五道题时,好几道都没思路,违反了规则到网上找了一圈,居然没找到答案,于是打算写这篇博客.不知是否有更好的实践 ...
- IO复用——select系统调用
1.select函数 此函数用于在一段时间内,监听用户感兴趣的文件描述符上的可读.可写和异常等事件. #include<sys/select.h> int select(int nfds, ...
- Python3全栈学习目录
http://www.cnblogs.com/wupeiqi/articles/4938499.html 文辉整理: http://blog.51cto.com/9272317/1869914
- 基于阿里云服务器Linux系统部署JavaWeb项目
前段时间刚完成一个JavaWeb项目,想着怎么部署到服务器上,边学边做,花了点时间终于成功部署了,这里总结记录一下过程中所遇到的问题及解决方法.之所以选择阿里云,考虑到它是使用用户最多也是最广泛的云服 ...
- CSS3 : transition 属性
CSS3的 transition 属性用于状态过度效果! 1.语法: transition: property duration timing-function delay; -moz-transit ...
- Python网络编程(进程通信、信号、线程锁、多线程)
什么是进程通讯的信号? 用过Windows的我们都知道,当我们无法正常结束一个程序时, 可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢? 同样的功能在Linux上是通过生成信号和捕获信号来实 ...
- 企业级Nginx Web服务优化实战
web优化一览总结表 优化类型 优化说明 优化方法 安全优化 隐藏nginx版本信息优化 修改nginx配置文件实现优化 server_tokens off: 修改nginx版本信息优化 修改ngin ...
- hdu 1556 Color the ball (区间更新 求某点值)
Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a ...