度限制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个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...
随机推荐
- HBase 参考信息
Apache HBase Region Splitting and Merging https://blog.cloudera.com/apache-hbase-region-splitting-a ...
- PTA --- Basic Level 1009 说反话
1009 说反话 (20 point(s)) 给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串.字符串由 ...
- Nginx实现负载均衡的方式有哪几种呢?
什么是负载均衡 当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃.为了避免服务器崩溃,让用户有更好的体验,我们通过负载均衡的方式来分担服务器压力. 我们 ...
- react中key的使用
面试题: 1). react/vue中的key的作用/内部原理 2). 为什么列表的key尽量不要用index 虚拟DOM的key的作用? 1). 简单的说: key是虚拟DOM对象的标识, 在更新显 ...
- 导包、时间模块【TIME、CALENDAR DATETIME】、SYS、OS, OS.PATH模块、项目开放周期&规范
导包 1.不考虑包的情况下直接from...直接导入文件夹下的具体模块 2. if __name__ == '__ma__' # 自执行 if __name__ == '模块名' # ...
- Linux常用目录名称
目录 用途 / 虚拟目录的根文件,通常不会在这里存储文件 /bin 二进制目录,存放许多用户的GNU工具 /boot 启动目录,存放启动文件 /dev 设备目录,Linux在这里创建设备节点 /etc ...
- 给Date的构造函数添加属性和方法
let d = Date.prototype; Object.defineProperties(d, { 'year': { get: function () { return this.getFul ...
- 6.maven的安装
JAVA配置 JAVA_HOME=安装目录 PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin CLASSPATH=%JAVA_HOME%\lib\dt.jar;%JAV ...
- python-day30(正式学习)
单例模式 什么是单例模式 单例模式:基于某种方法实例化多次得到实例是同一个 为什么用单例模式 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例 用类方法来实现 ...
- 为什么说Python采用的是基于值的内存管理模式?
Python中的变量并不直接存储值,而是存储了值的内存地址或者引用,假如为不同变量赋值为相同值,这个值在内存中只有一份,多个变量指向同一块内存地址.