HDU 4126 Genghis Khan the Conqueror MST+树形dp
题意:
给定n个点m条边的无向图。
以下m行给出边和边权
以下Q个询问。
Q行每行给出一条边(一定是m条边中的一条)
表示改动边权。
(数据保证改动后的边权比原先的边权大)
问:改动后的最小生成树的权值是多少。
每一个询问互相独立(即每次询问都是对于原图改动)
保证没有重边。
求:全部改动后的最小生成树权值的平均值。
思路:
首先跑一个最小生成树。
求得这个MST的权值 int mst;
对于每一个询问(u.v,dis);
若(u,v) 不是MST上的边,则此时的权值就是 mst
否则我们断开树边(u,v),然后找u点集和v点集之间的边中权值最小的边cost[u][v];
这样当前的权值就是 mst - g[u][v] + min(cost[u][v], dis);
剩下就是怎样计算cost;
MST会求得一个无根树。
我们把无根树转成以u为根时 ,对于v子树事实上是不变的。
剩下就是简单dp了
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <queue>
#include <algorithm>
#include <cmath>
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if(x>9) pt(x/10);
putchar(x%10+'0');
}
typedef long long ll;
using namespace std;
const ll inf = 100000000;
const int N = 3005;
ll g[N][N], d[N], mst, cost[N][N];
bool vis[N], choose[N][N];
int n, m;
vector<int> G[N];
ll dfs(int u, int fa, int src){
ll siz = inf;
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(v == fa)continue;
ll tmp = dfs(v, u, src);
siz = min(siz, tmp);
cost[u][v] = cost[v][u] = min(cost[u][v], tmp);
}
if(fa != src)
siz = min(siz, g[u][src]);
return siz;
}
int pre[N];
void MST(){
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
cost[i][j] = g[i][j] = inf, choose[i][j] = 0; while(m--){
int u, v; ll dis; rd(u);rd(v); rd(dis);
g[u][v] = g[v][u] = min(g[u][v], dis);
}
for(int i = 0; i < n; i++)
{
d[i] = inf;
G[i].clear();
vis[i] = 0;
pre[i] = -1;
}
d[0] = 0;
mst = 0;
for(int i = 0; i < n; i++)
{
int pos = -1;
for(int j = 0; j < n; j++)
if(!vis[j] &&(pos == -1 || d[pos] > d[j]))
pos = j;
if(pre[pos]!=-1)
{
G[pos].push_back(pre[pos]);
G[pre[pos]].push_back(pos);
choose[pos][pre[pos]] = choose[pre[pos]][pos] = 1;
}
for(int j = 0; j < n; j++)
if(d[j] > g[j][pos])
{
d[j] = g[j][pos];
pre[j] = pos;
}
vis[pos] = 1;
mst += d[pos];
}
} int main() {
int q, u, v; ll dis;
while(cin>>n>>m, n+m) {
MST();
for(int i = 0; i < n; i++)
dfs(i, -1, i);
rd(q);
ll ans = 0;
for(int i = 1; i <= q; i++) {
rd(u); rd(v); rd(dis);
if(choose[u][v] == false)
ans += mst;
else
ans += mst - g[u][v] + min(cost[u][v], dis);
}
printf("%.4f\n",(double)ans/(double)q);
}
return 0;
}
HDU 4126 Genghis Khan the Conqueror MST+树形dp的更多相关文章
- HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 Genghis Khan the Conqueror Time Limit: 10000/50 ...
- HDU 4126 Genghis Khan the Conqueror (树形DP+MST)
题意:给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边 (可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个 ...
- hdu4126Genghis Khan the ConquerorGenghis Khan the Conqueror(MST+树形DP)
题目请戳这里 题目大意:给n个点,m条边,每条边权值c,现在要使这n个点连通.现在已知某条边要发生突变,再给q个三元组,每个三元组(a,b,c),(a,b)表示图中可能发生突变的边,该边一定是图中的边 ...
- hdu4126Genghis Khan the Conqueror (最小生成树+树形dp)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others) Total Submiss ...
- HDU-4126 Genghis Khan the Conqueror 树形DP+MST (好题)
题意:给出一个n个点m条边的无向边,q次询问每次询问把一条边权值增大后问新的MST是多少,输出Sum(MST)/q. 解法:一开始想的是破圈法,后来想了想应该不行,破圈法应该只能用于加边的情况而不是修 ...
- 刷题总结——Genghis Khan the Conqueror (hdu4126)
题目: Genghis Khan(成吉思汗)(1162-1227), also known by his birth name Temujin(铁木真) and temple name Taizu(元 ...
- UVA- 1504 - Genghis Khan the Conqueror(最小生成树-好题)
题意: n个点,m个边,然后给出m条边的顶点和权值,其次是q次替换,每次替换一条边,给出每次替换的边的顶点和权值,然后求出这次替换的最小生成树的值; 最后要你输出:q次替换的平均值.其中n<30 ...
- uvalive 5834 Genghis Khan The Conqueror
题意: 给出一个图,边是有向的,现在给出一些边的变化的信息(权值大于原本的),问经过这些变换后,MST总权值的期望,假设每次变换的概率是相等的. 思路: 每次变换的概率相等,那么就是求算术平均. 首先 ...
- 【Uvalive 5834】 Genghis Khan the Conqueror (生成树,最优替代边)
[题意] 一个N个点的无向图,先生成一棵最小生成树,然后给你Q次询问,每次询问都是x,y,z的形式, 表示的意思是在原图中将x,y之间的边增大(一定是变大的)到z时,此时最小生成数的值是多少.最后求Q ...
随机推荐
- Please verify you invoked Maven from the correct directory
解决办法: 在cmd中,把当前路径转换到一个含有pom文件的 项目路径下 再使用 类似下面的deploy就行 mvn deploy:deploy-file -DgroupId=com.taobao.n ...
- Delphi回调函数及其使用
Delphi回调函数及其使用 1 回调函数的概述 回调函数是这样一种机制:调用者在初始化一个对象(这里的对象是泛指,包括OOP中的对象.全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的 ...
- 与众不同 windows phone (25) - Input(输入)之捕获 UIElement 之外的触控操作, Silverlight 方式捕获手势操作, XNA 方式捕获手势操作, 多点触控
原文:与众不同 windows phone (25) - Input(输入)之捕获 UIElement 之外的触控操作, Silverlight 方式捕获手势操作, XNA 方式捕获手势操作, 多点触 ...
- 怎么获取Spring的ApplicationContext
在 WEB 开发中,可能会非常少须要显示的获得 ApplicationContext 来得到由 Spring 进行管理的某些 Bean, 今天我就遇到了,在这里和大家分享一下, WEB 开发中,怎么获 ...
- Codeforce 143B - Help Kingdom of Far Far Away 2
B. Help Kingdom of Far Far Away 2 time limit per test 2 seconds memory limit per test 256 megabytes ...
- IE 兼容模式
兼容模式的由来 早期的浏览器, IE 独大.这也就导致其很多东西和w3c 的标准有很多不一样的地方.譬如他有自己才看的懂得自定义Tag. 一个熟悉的名词--浏览器大战, 形象的刻画了这期间发生的事情. ...
- cocos2d-x3.2下使用Umeng 64位SDK注意事项
友盟官方的样例中已经有了Cocos2d-x的Demo使用起来也是比較方便的.但在64位的版本号使用时须要注意 32位SDK改动: 将Xcode中Build Settings的Architectures ...
- python语言学习5——输入和输出
输出 用print()在括号中加上字符串,就可以向屏幕上输出指定的文字. 注意点: 字符串用的是单引号 碰到逗号输出时就会输出一个空格 输入 python提供了一个input(),可以让用户输入一个字 ...
- 什么是Spring?Spring是什么?
Spring概述: Spring是一个开源框架,是为了解决企业应用程序开发复杂性而开发的. 从简单性.可測试性和松耦合的角度而言,不论什么java应用都能够从Spring中受益. 简而言之,Sprin ...
- WebSocket聊天室demo
根据Socket异步聊天室修改成WebSocket聊天室 WebSocket特别的地方是 握手和消息内容的编码.解码(添加了ServerHelper协助处理) ServerHelper: using ...