度限制MST
POJ1639 顶点度数限制的最小生成树
做法:首先把和顶点相连的X条边全部删掉 得到顶点和 X个连通块
然后求出这X个连通块的MST 再把X条边连接回去这样我们就首先求出了X度MST
知道了X度MST 我们接下来要求X+1度MST 也就是再给顶点一条边 但是加上了这条边就会生成一个环
我们需要删掉这个环上最大权值的边
所有我们每次从N度向N+1度推进的时候需要O(N)DP求出并记录顶点到其他点的权值最大边
然后我们枚举还没有连上的边 如果删掉的边不会比加入的边大的话 就不继续推进了(剪枝)
/*Huyyt*/
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + ;
const int gakki = + + + + 1e9;
const int MAXN = 1e2 + , MAXM = 2e4 + ;
/*int to[MAXM << 1], nxt[MAXM << 1], Head[MAXN], ed = 1;
int cost[MAXM << 1];
inline void addedge(int u, int v, int c)
{
to[++ed] = v;
nxt[ed] = Head[u];
cost[ed] = c;
Head[u] = ed;
}*/
int dis[][];
int par[];
map<string, int> mp;
string mpu, mpv;
bool connect[];
int n, K;
int cnt = , root, costnow, ans = , ccnt = ;
int dp[];
struct node
{
int u, v, c;
} edge[], cmin[], rootedge[], cur, choose[];
bool cmp(node a, node b)
{
return a.c < b.c;
}
int findpar(int x)
{
return par[x] == x ? x : par[x] = findpar(par[x]);
}
void init()
{
for (int i = ; i <= n; i++)
{
dp[i] = -;
choose[i].c = -;
}
}
void dfs(int x, int pre)
{
node better;
for (int v = ; v <= n; v++)
{
if (v != pre && (dis[x][v] != ))
{
if (dis[x][v] > choose[x].c)
{
choose[v].u = x, choose[v].v = v, choose[v].c = dis[x][v];
dp[v] = dis[x][v];
}
else
{
choose[v] = choose[x];
dp[v] = dp[x];
}
dfs(v, x);
}
}
}
int main()
{
scanf("%d", &n);
for (int i = ; i <= n + ; i++)
{
par[i] = i;
cmin[i].c = ;
for (int j = ; j <= n + ; j++)
{
dis[i][j] = ;
}
}
mp["Park"] = ;
for (int i = ; i <= n; i++)
{
cin >> mpu >> mpv >> costnow;
if (!mp[mpu])
{
mp[mpu] = ++cnt;
}
if (!mp[mpv])
{
mp[mpv] = ++cnt;
}
edge[i].u = mp[mpu], edge[i].v = mp[mpv];
edge[i].c = costnow;
//cout << edge[i].u << " " << edge[i].v << " " << costnow << endl;
if (edge[i].u == || edge[i].v == )
{
rootedge[++ccnt] = edge[i];
}
}
scanf("%d", &K);
sort(edge + , edge + + n, cmp);
for (int i = ; i <= n; i++)
{
int u1, v1;
u1 = edge[i].u, v1 = edge[i].v;
if (u1 != && v1 != )
{
int fx = findpar(u1), fy = findpar(v1);
if (fx != fy)
{
par[fx] = fy;
dis[u1][v1] = dis[v1][u1] = edge[i].c;
ans += edge[i].c;
//cout << " u " << u1 << " v " << v1 << " " << ans << endl;
}
}
}
for (int i = ; i <= ccnt; i++)
{
int u1, v1;
u1 = rootedge[i].u, v1 = rootedge[i].v;
if (u1 != )
{
int fx = findpar(u1);
if (cmin[fx].c > rootedge[i].c)
{
cmin[fx] = rootedge[i];
}
}
else
{
int fx = findpar(v1);
if (cmin[fx].c > rootedge[i].c)
{
cmin[fx] = rootedge[i];
}
}
}
int m = ;
for (int i = ; i <= cnt; i++)
{
int fx = findpar(i);
if (!connect[fx])
{
m++;
connect[fx] = true;
cur = cmin[fx];
dis[cur.u][cur.v] = dis[cur.v][cur.u] = cur.c;
ans += cur.c;
//cout << " i " << i << " u " << cur.u << " v " << cur.v << " " << ans << endl;
for (int j = ; j <= ccnt; j++)
{
if (rootedge[j].u == cur.u && rootedge[j].v == cur.v)
{
rootedge[j].c = -;
break;
}
}
}
}
for (int i = m + ; i <= K; i++)
{
init();
dfs(, -);
int ansmanx = ;
node best;
int want;
int where;
for (int j = ; j <= ccnt; j++)
{
if (rootedge[j].c != -)
{
int u1, v1;
u1 = rootedge[j].u, v1 = rootedge[j].v;
if (u1 != )
{
if (dp[u1] - rootedge[j].c > ansmanx)
{
where = j;
best = rootedge[j];
want = u1;
ansmanx = dp[u1] - rootedge[j].c;
}
}
else
{
if (dp[v1] - rootedge[j].c > ansmanx)
{
where = j;
best = rootedge[j];
want = v1;
ansmanx = dp[v1] - rootedge[j].c;
}
}
}
}
if (ansmanx == )
{
break;
}
dis[best.u][best.v] = dis[best.v][best.u] = best.c;
dis[choose[want].u][choose[want].v] = dis[choose[want].v][choose[want].u] = ;
rootedge[where].c = -;
ans -= ansmanx;
}
printf("Total miles driven: %d\n", ans);
//cout << "Total miles driven: " << ans << endl;
return ;
}
//度生成树
度限制MST的更多相关文章
- poj 1639 Picnic Planning 度限制mst
https://vjudge.net/problem/POJ-1639 题意: 有一群人,他们要去某一个地方,每个车可以装无数个人,给出了n条路,包含的信息有路连接的地方,以及路的长度,路是双向的,但 ...
- K度限制MST poj 1639
/* k度限制MST:有一个点的度<=k的MST poj 1639 要求1号点的度不超过k 求MST 我们先把1号点扔掉 跑MST 假设有sum个连通分支 然后把这sum个分支连到1上 就得到了 ...
- CF-125E MST Company (单度限制最小生成树)
参考红宝书 题目链接 对除 1 号点顶点外的点集,求一次最小生成森林,对于最小生成森林的联通分量,选择最短的一条边与 1 号点相连.设此时 1 号点的度为 \(k_0\),如果 \(k_0\lt L\ ...
- 基于MST的立体匹配及相关改进(A Non-Local Cost Aggregation Method for Stereo Matching)
怀着很纠结的心情来总结这篇论文,这主要是因为作者提虽然供了源代码,但是我并没有仔细去深究他的code,只是把他的算法加进了自己的项目.希望以后有时间能把MST这一结构自己编程实现!! 论文题目是基于非 ...
- 2015baidu复赛2 连接的管道(mst && 优先队列prim)
连接的管道 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST
E. Minimum spanning tree for each edge Connected undirected weighted graph without self-loops and ...
- POJ 3241 Object Clustering(Manhattan MST)
题目链接:http://poj.org/problem?id=3241 Description We have N (N ≤ 10000) objects, and wish to classify ...
- UVA 11354 Bond 邦德 (RMQ,最小瓶颈MST)
题意: n个城市,m条路,每条路有个危险值,要使得从s走到t的危险值最小.回答q个询问,每个询问有s和t,要求输出从s到t最小的危险值.(5万个点,10万条边) 思路: 其实要求的是任意点对之间的最小 ...
- UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)
题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...
随机推荐
- FICO相关号码范围IMG设定
一.定义会计文件号码范围——FBN1 二.定义总账检视的文件号码范围——FAGL_DOCNR 三.指派客户科目群组的号码范围 四.定义供应商号码范围——XKN1 五.维护订单号码范围——KONK
- Python浅拷贝与深拷贝(可变对象与不可变对象)
第一次遇到深拷贝和浅拷贝的问题是用python在一个for循环中对一个list赋值,使用的语句是 a = b 这个b会不断带入循环,每次计算得到,最后发现list乱七八糟的,后来才发现,python中 ...
- Cannot get a NUMERIC value from a STRING cell? 已解决
最近在写项目中用到了excel的导入,遇到了Cannot get a NUMERIC value from a STRING cell的报错.原因是无法从纯数字的单元格用获取String的方式获取.跟 ...
- pypy3.6的下载地址和安装第三方依赖
1.不同版本的下载链接 建议使用此链接:https://bitbucket.org/pypy/pypy/downloads/ 官网的:http://doc.pypy.org/en/latest/rel ...
- Java内存模型 (一)什么是进程?什么是线程?进程和线程之间的区别是什么?
什么是进程?什么是线程? 进程是系统中正在运行的一个程序,程序一旦运行就是进程. 进程可以看成程序执行的一个实例.进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间.一个进程无法访问另一个进程 ...
- java学习-2
类的定义 成员变量: 变量类型 变量名称 成员方法:public void 方法名称(){} 注意:成员变量是直接定义在类当中方法外面 创建对象使用类 导包.指出需要的类在什么位置 import 包名 ...
- luoguP3390(矩阵快速幂模板题)
链接:https://www.luogu.org/problemnew/show/P3390 题意:矩阵快速幂模板题,思路和快速幂一致,只需提供矩阵的乘法即可. AC代码: #include<c ...
- 在PostgreSQL中 pg_start_backup 做了什么?
# 在PostgreSQL中 pg_start_backup 做了什么?HM 2019-07-30 ## pg_start_backup 做一个备份开始标记,还做了一些其他的操作,下面进行探寻. * ...
- C++多线程基础学习笔记(八)
shared_futrue和futrue_status的用法 shared_futrue是一个类模板,类似于futrue,不同的是它的成员函数get()可以使用多次,因为是复制数据,而futrue的g ...
- CodeForce20C
这是一个裸的最短路的模板题,但是它需要输出路径. 用dijkstra的话首先敲一个最短路的板子,其次开一个数组p[]来记录路径,但是怎么存呢?我们需要记录每一个点的前驱,因为如果记录后边的话,一个点可 ...