MST + 树形 dp
Our story is about Jebei Noyan(哲别), who was one of the most famous
generals in Genghis Khan’s cavalry. Once his led the advance troop to
invade a country named Pushtuar. The knights rolled up all the cities in
Pushtuar rapidly. As Jebei Noyan’s advance troop did not have enough
soldiers, the conquest was temporary and vulnerable and he was waiting
for the Genghis Khan’s reinforce. At the meantime, Jebei Noyan needed to
set up many guarders on the road of the country in order to guarantee
that his troop in each city can send and receive messages safely and
promptly through those roads.
There were N cities in Pushtuar and there were bidirectional roads
connecting cities. If Jebei set up guarders on a road, it was totally
safe to deliver messages between the two cities connected by the road.
However setting up guarders on different road took different cost based
on the distance, road condition and the residual armed power nearby.
Jebei had known the cost of setting up guarders on each road. He wanted
to guarantee that each two cities can safely deliver messages either
directly or indirectly and the total cost was minimal.
Things will always get a little bit harder. As a sophisticated
general, Jebei predicted that there would be one uprising happening in
the country sooner or later which might increase the cost (setting up
guarders) on exactly ONE road. Nevertheless he did not know which road
would be affected, but only got the information of some suspicious road
cost changes. We assumed that the probability of each suspicious case
was the same. Since that after the uprising happened, the plan of
guarder setting should be rearranged to achieve the minimal cost, Jebei
Noyan wanted to know the new expected minimal total cost immediately
based on current information.
For each test case, the first line contains two integers N and M
(1<=N<=3000, 0<=M<=N×N), demonstrating the number of cities
and roads in Pushtuar. Cities are numbered from 0 to N-1. In the each of
the following M lines, there are three integers x
i, y
i and c
i(c
i<=10
7), showing that there is a bidirectional road between x
i and y
i, while the cost of setting up guarders on this road is c
i. We guarantee that the graph is connected. The total cost of the graph is less or equal to 10
9.
The next line contains an integer Q (1<=Q<=10000) representing
the number of suspicious road cost changes. In the following Q lines,
each line contains three integers X
i, Y
i and C
i showing that the cost of road (X
i, Y
i) may change to C
i (C
i<=10
7). We guarantee that the road always exists and C
i is larger than the original cost (we guarantee that there
is at most one road connecting two cities directly). Please note that
the probability of each suspicious road cost change is the same.
OutputFor each test case, output a real number demonstrating the
expected minimal total cost. The result should be rounded to 4 digits
after decimal point.
Sample Input
- 3 3
- 0 1 3
- 0 2 2
- 1 2 5
- 3
- 0 2 3
- 1 2 6
- 0 1 6
- 0 0
Sample Output
- 6.0000
Hint
- The initial minimal cost is 5 by connecting city 0 to 1 and city 0 to 2. In the first suspicious case, the minimal total cost is increased to 6;
- the second case remains 5; the third case is increased to 7. As the result, the expected cost is (5+6+7)/3 = 6.
题意:给你一个无向图,每次更换一条边的长度,一定是增加,问每次让图连通的最小的花费。
思路分析:先求一个 mst, 然后dp预处理一个去掉边(i,j)后此图还是连通的最小的花费。
代码示例:
- int n, m;
- int edge[3005][3005];
- int f[3005];
- struct node
- {
- int u, v, c;
- node(int _u=0, int _v=0, int _c=0):u(_u), v(_v), c(_c){}
- bool operator< (const node &pp){
- return c < pp.c;
- }
- }pre[3005*3005];
- vector<int>ve[3005];
- int fid(int x){
- if (x != f[x]) f[x] = fid(f[x]);
- return f[x];
- }
- int cost;
- bool pt[3005][3005];
- void kru(){
- sort(pre+1, pre+1+m);
- cost = 0;
- for(int i = 1; i <= m; i++){
- int u = pre[i].u, v = pre[i].v, c = pre[i].c;
- int fu = fid(u), fv = fid(v);
- if (fu != fv){
- f[fu] = fv;
- cost += c;
- ve[u].push_back(v);
- ve[v].push_back(u);
- pt[u][v] = pt[v][u] = true;
- }
- }
- }
- int dp[3005][3005];
- int dfs(int cur, int x, int fa){ //dfs求的是它的所有孩子结点与 cur 连接的最小值
- int res = inf;
- for(int i = 0; i < ve[x].size(); i++){
- int to = ve[x][i];
- if (to == fa) continue;
- int mid = dfs(cur, to, x);
- res = min(res, mid);
- dp[x][to] = dp[to][x] = min(dp[to][x], mid); // 注意这里是mid,指的是去掉与当前结点相连的边后其所指的再次联通两部分的最小花费
- }
- if (cur != fa){ // 只有当不相等的时候指的才是其不在最小生成树上的边
- res = min(res, edge[cur][x]);
- }
- return res;
- }
- void init() {
- memset(edge, inf, sizeof(edge));
- memset(pt, false, sizeof(pt));
- memset(dp, inf, sizeof(dp));
- for(int i = 1; i <= n; i++) ve[i].clear(), f[i] = i;
- }
- int x, y, z, q;
- int main() {
- //freopen("in.txt", "r", stdin);
- //freopen("out.txt", "w", stdout);
- while(~scanf("%d%d", &n, &m) && n+m){
- init();
- for(int i = 1; i <= m; i++){
- scanf("%d%d%d", &x, &y, &z);
- x++, y++;
- edge[x][y] = edge[y][x] = z;
- pre[i] = node(x, y, z);
- }
- kru();
- for(int i = 1; i <= n; i++) dfs(i, i, -1);
- scanf("%d", &q);
- double sum = 0;
- for(int i = 1; i <= q; i++){
- scanf("%d%d%d", &x, &y, &z);
- x++, y++;
- if (!pt[x][y]) sum += 1.0*cost;
- else {
- sum += 1.0*(cost-edge[x][y])+1.0*min(z, dp[x][y]);
- }
- }
- printf("%.4lf\n", sum/q);
- }
- return 0;
- }
MST + 树形 dp的更多相关文章
- hdu4756 Install Air Conditioning(MST + 树形DP)
题目请戳这里 题目大意:给n个点,现在要使这n个点连通,并且要求代价最小.现在有2个点之间不能直接连通(除了第一个点),求最小代价. 题目分析:跟这题一样样的,唉,又是原题..先求mst,然后枚举边, ...
- hdu4126(MST + 树形dp
题意: 这个题目和hdu4756差不多,是给你一个图,然后是q次改变边的权值,权值只增不减,最后问你每次改变之后的最小树的平均值是多少. 思路:(prim+树形dp) 先跑一边 ...
- hdu 4756 MST+树形dp ****
题意:给你n(n = 1000)个二维点,第一个点是power plant,还有n - 1个点是dormitories.然后现在知道有一条寝室到寝室的边是不能连的,但是我们不知道是哪条边,问这种情况下 ...
- hdu4126Genghis Khan the ConquerorGenghis Khan the Conqueror(MST+树形DP)
题目请戳这里 题目大意:给n个点,m条边,每条边权值c,现在要使这n个点连通.现在已知某条边要发生突变,再给q个三元组,每个三元组(a,b,c),(a,b)表示图中可能发生突变的边,该边一定是图中的边 ...
- HDU 4126 Genghis Khan the Conqueror MST+树形dp
题意: 给定n个点m条边的无向图. 以下m行给出边和边权 以下Q个询问. Q行每行给出一条边(一定是m条边中的一条) 表示改动边权. (数据保证改动后的边权比原先的边权大) 问:改动后的最小生成树的权 ...
- HDU 4756 Install Air Conditioning (MST+树形DP)
题意:n-1个宿舍,1个供电站,n个位置每两个位置都有边相连,其中有一条边不能连,求n个位置连通的最小花费的最大值. 析:因为要连通,还要权值最小,所以就是MST了,然后就是改变一条边,然后去找出改变 ...
- HDU-4126 Genghis Khan the Conqueror 树形DP+MST (好题)
题意:给出一个n个点m条边的无向边,q次询问每次询问把一条边权值增大后问新的MST是多少,输出Sum(MST)/q. 解法:一开始想的是破圈法,后来想了想应该不行,破圈法应该只能用于加边的情况而不是修 ...
- hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)
题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others) Memory Limit: ...
- codeforces 709E E. Centroids(树形dp)
题目链接: E. Centroids time limit per test 4 seconds memory limit per test 512 megabytes input standard ...
随机推荐
- 推荐C++程序员阅读《CLR via C#》
这本书的作者Jeffrey Richter也是<Windows核心编程>的作者. <Windows核心编程>更多的是对window系统相关知识的挖掘积累.<CLR via ...
- 无限调用函数add(1)(2)(3)......
无限调用函数,并且累计结果 其实这也算一道面试题吧,笔者曾经被提问过,可惜当时没能答上来...
- Intellij IDEA 如何使用Jrebel热部署
My Jrebel 已经不再提供免费使用了,或使用破解版Jrebel 或可以移步至 HotSwapAgent,或使用破解的Jrebel. 一个java web项目,在写的过程中我们需要不断调试,如果没 ...
- CF1209
CF1209 A B 水题不管 C 因为要求最终整个序列是要单调的 所以我们就考虑枚举断点$x$ 之后把$<x$的数放到第一个集合 把$> x$的数放到第二个集合 至于$=x$的数 他能放 ...
- 【20.51%】【codeforces 610D】Vika and Segments
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- HDU4609 FFT+组合计数
HDU4609 FFT+组合计数 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意: 找出n根木棍中取出三根木棍可以组成三角形的概率 题解: ...
- presto,dremio,spark-sql与ranger的整合记录
dremio,spark-sql,presto和ranger的整合 当前,ranger没有现成的插件来管理dremio,spark-sql,presto. 暂时使用的方法是新建一个用户,如presto ...
- Visual Studio 2017 安装心得
既然VS2017已经发布了,就想安装一下试试,先卸载VS2015, 网上有个完全卸载的东东,https://github.com/Microsoft/VisualStudioUninstaller/r ...
- Mysql 最全查询语句
基本查询语句及语法: select distinct from where group by having limit 一.单表查询 前期表与数据准备: # 创建一张部门表 create table ...
- $SCOI2009\ windy$数 数位$dp$
\(Sol\) 数位\(dp\)常规套路题. \(dp[i][j]\)表示从低位到高位填到第\(i\)位且第\(i\)位的数字为\(j\)的方案数.答案就是\(sol(r)-sol(l+1).\)这里 ...