题意:

给定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的更多相关文章

  1. HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 Genghis Khan the Conqueror Time Limit: 10000/50 ...

  2. HDU 4126 Genghis Khan the Conqueror (树形DP+MST)

    题意:给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边 (可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个 ...

  3. hdu4126Genghis Khan the ConquerorGenghis Khan the Conqueror(MST+树形DP)

    题目请戳这里 题目大意:给n个点,m条边,每条边权值c,现在要使这n个点连通.现在已知某条边要发生突变,再给q个三元组,每个三元组(a,b,c),(a,b)表示图中可能发生突变的边,该边一定是图中的边 ...

  4. hdu4126Genghis Khan the Conqueror (最小生成树+树形dp)

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others) Total Submiss ...

  5. HDU-4126 Genghis Khan the Conqueror 树形DP+MST (好题)

    题意:给出一个n个点m条边的无向边,q次询问每次询问把一条边权值增大后问新的MST是多少,输出Sum(MST)/q. 解法:一开始想的是破圈法,后来想了想应该不行,破圈法应该只能用于加边的情况而不是修 ...

  6. 刷题总结——Genghis Khan the Conqueror (hdu4126)

    题目: Genghis Khan(成吉思汗)(1162-1227), also known by his birth name Temujin(铁木真) and temple name Taizu(元 ...

  7. UVA- 1504 - Genghis Khan the Conqueror(最小生成树-好题)

    题意: n个点,m个边,然后给出m条边的顶点和权值,其次是q次替换,每次替换一条边,给出每次替换的边的顶点和权值,然后求出这次替换的最小生成树的值; 最后要你输出:q次替换的平均值.其中n<30 ...

  8. uvalive 5834 Genghis Khan The Conqueror

    题意: 给出一个图,边是有向的,现在给出一些边的变化的信息(权值大于原本的),问经过这些变换后,MST总权值的期望,假设每次变换的概率是相等的. 思路: 每次变换的概率相等,那么就是求算术平均. 首先 ...

  9. 【Uvalive 5834】 Genghis Khan the Conqueror (生成树,最优替代边)

    [题意] 一个N个点的无向图,先生成一棵最小生成树,然后给你Q次询问,每次询问都是x,y,z的形式, 表示的意思是在原图中将x,y之间的边增大(一定是变大的)到z时,此时最小生成数的值是多少.最后求Q ...

随机推荐

  1. 一int考虑什么类型的多少字节

    一int表示的字节数? 问题是,我们经常得到的答案4. 但int究竟占多少个字节,却跟你的机器环境有关. As you can see, the typical data type sizes mat ...

  2. XPSP2 PSDK(还有lostspeed)

    XPSP2 PSDK Full Download with Local Install Use the full download to copy the entire Windows XP SP2 ...

  3. sqlserver 操作技巧

    1.将不同库中的一张表数据导入到另外一张表中去 ① 两张表多存在实体,两表的字段相同,字段的顺序相同的话. insert into 表B select * from 表A ② 两张表多存在实体,两表的 ...

  4. QS Network(最小生成树)

    题意:若两个QS之间要想连网,除了它们间网线的费用外,两者都要买适配器, 求使所有的QS都能连网的最小费用. 分析:这个除了边的权值外,顶点也有权值,因此要想求最小价值,必须算边及顶点的权值和. 解决 ...

  5. 14.4.3.4 Configuring InnoDB Buffer Pool Prefetching (Read-Ahead) 配置InnoDB Buffer pool 预读

    14.4.3.4 Configuring InnoDB Buffer Pool Prefetching (Read-Ahead) 配置InnoDB Buffer pool 预读 一个预读请求 是一个I ...

  6. python爬虫抓站的一些技巧总结

    使用python爬虫抓站的一些技巧总结:进阶篇 一.gzip/deflate支持现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,以VeryCD的主页为例,未压缩版本247K,压缩了以后45 ...

  7. Ubuntu下is not in the sudoers file 问题解决

    在Ubuntu12.04 下,使用sudo apt-get install XXX 时,突然跳出 username is not in the sudoers file的问题 然后我一查此userna ...

  8. tracert路由跟踪命令分析判断

    可能有的会使用路由跟踪命令 ,可是却看不太明确显示出来的结果.结合我的来说明一下. (1)tracert命令介绍 tracert是路由跟踪命令,通过该命令的返回结果,能够获得本地到达目标主机所经过的网 ...

  9. 《转》MFC网络编程学习

    原地址:http://www.cnblogs.com/renyuan/archive/2013/06/04/3117006.html要学习好网路编程,主要看以下几个方面: 1.掌握概念,诸如:同步(S ...

  10. QTableView 固定列宽度(鼠标拖动后,仍可固定)

    QTableView 提供一个函数: void QTableView::setColumnWidth ( int column, int width ) 用于设置column指定的列的宽度 但setC ...