HDU-4126 Genghis Khan the Conqueror 树形DP+MST (好题)
题意:给出一个n个点m条边的无向边,q次询问每次询问把一条边权值增大后问新的MST是多少,输出Sum(MST)/q。
解法:一开始想的是破圈法,后来想了想应该不行,破圈法应该只能用于加边的情况而不是修改边,因为加边可以保证以前MST不用的边加边之后也一定不用,但是修改边不能保证以前不用的边修改边之后会不会再用。
正解是参考https://blog.csdn.net/Ramay7/article/details/52236040这位大佬的。

大佬真的分析得巨好。我的理解就是:假如我们要计算dp[u][v]代表去掉MST上u-v这条边之后能替代的最好边,设u这一边的连通点集是(u1,u2,u3...),v这一边的点集是(v1,v2,v3...),那么我们朴素算法是暴力枚举每一对ui和vi然后取最小值,显然这样超时。用树形DP的方法是,我们枚举一个根节点rt,然后dfs一边计算以rt为根节点的时候的MST的所有边的dp值,计算方式就是dp[u][v]=min(dis[y][rt])(即子树中到根rt的最小值)。枚举完根节点rt之后我们的dp数组就出来了。 为什么这样能达到朴素算法一样的效果呢?因为考虑我们每一次rt对dp[u][v]的贡献,显然每一个rt都是在点集(u1,u2,u3...)中的,然后这次dfs可以计算(u1,u2,u3...)中的某一个ui和所有的(v1,v2,v3...)的点对对答案的贡献,然后所以的rt加起来必定等于(u1,u2,u3...)。 这里说得有点乱了,就是这样:
(rt=u1)x(v1,v2,v3...)+(rt=u2)*(v1,v2,v3...)+(rt=u3)*(v1,v2,v3...)+....(rt=ui)*(v1,v2,v3...) == (u1,u2,u3...)*(v1,v2,v3...) (上面说的一大堆想说的就是这个等式的意思qwq)
最后处理下询问看看修改边在不在原MST上,就可以获得AC了。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=3e3+;
int n,m,fa[N],dis[N][N],dp[N][N];
LL sum,ans;
struct edge{
int x,y,z;
bool operator < (const edge &rhs) const {
return z<rhs.z;
}
}e[N*N];
bool mst[N][N]; int cnt,head[N],nxt[N<<],to[N<<];
void add_edge(int x,int y) {
nxt[++cnt]=head[x]; to[cnt]=y; head[x]=cnt;
} int getfa(int x) { return x==fa[x] ? x : fa[x]=getfa(fa[x]); } void Kruskal() {
sort(e+,e+m+);
for (int i=;i<=n;i++) fa[i]=i;
int num=;
for (int i=;i<=m;i++) {
int fx=getfa(e[i].x),fy=getfa(e[i].y);
if (fx==fy) continue;
fa[fx]=fa[fy];
add_edge(e[i].x,e[i].y); add_edge(e[i].y,e[i].x);
mst[e[i].x][e[i].y]=mst[e[i].y][e[i].x]=;
sum+=e[i].z;
if (++num==n) break;
}
} int dfs(int rt,int x,int fa) {
int Min=0x3f3f3f3f;
for (int i=head[x];i;i=nxt[i]) {
int y=to[i];
if (y==fa) continue;
int tmp=dfs(rt,y,x);
Min=min(Min,tmp);
dp[x][y]=min(dp[x][y],tmp); //用子树的Min更新dp[][]
dp[y][x]=min(dp[y][x],tmp);
}
if (dis[rt][x] && !mst[rt][x]) Min=min(Min,dis[rt][x]); //更新Min
return Min;
} int main()
{
while (scanf("%d%d",&n,&m) && n) {
cnt=; for (int i=;i<=n;i++) head[i]=;
for (int i=;i<=n;i++) for (int j=;j<=n;j++) dis[i][j]=mst[i][j]=,dp[i][j]=0x3f3f3f3f;
for (int i=;i<=m;i++) {
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
e[i].x++; e[i].y++;
dis[e[i].x][e[i].y]=dis[e[i].y][e[i].x]=e[i].z;
}
sum=; ans=;
Kruskal(); for (int i=;i<=n;i++) dfs(i,i,); //每个点做根节点dfs一次 int q; scanf("%d",&q);
for (int i=;i<=q;i++) {
int x,y,z; scanf("%d%d%d",&x,&y,&z);
x++; y++;
if (!mst[x][y]) ans+=sum; //不在MST上
else { //在MST上
LL tdis=sum-dis[x][y]+min(z,dp[x][y]);
ans+=tdis;
}
}
printf("%.4lf\n",(double)ans/q);
}
return ;
}
HDU-4126 Genghis Khan the Conqueror 树形DP+MST (好题)的更多相关文章
- HDU 4126 Genghis Khan the Conqueror (树形DP+MST)
题意:给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边 (可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个 ...
- 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 MST+树形dp
题意: 给定n个点m条边的无向图. 以下m行给出边和边权 以下Q个询问. Q行每行给出一条边(一定是m条边中的一条) 表示改动边权. (数据保证改动后的边权比原先的边权大) 问:改动后的最小生成树的权 ...
- 「日常训练」 Genghis Khan the Conqueror(HDU-4126)
题意 给定\(n\)个点和\(m\)条无向边(\(n\le 3000\)),需要将这\(n\)个点连通.但是有\(Q\)次(\(Q\le 10^4\))等概率的破坏,每次破坏会把\(m\)条边中的某条 ...
- 刷题总结——Genghis Khan the Conqueror (hdu4126)
题目: Genghis Khan(成吉思汗)(1162-1227), also known by his birth name Temujin(铁木真) and temple name Taizu(元 ...
- HDU 1520.Anniversary party 基础的树形dp
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- HDU 3586 Information Disturbing(二分+树形dp)
http://acm.split.hdu.edu.cn/showproblem.php?pid=3586 题意: 给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超 ...
- HDU 5682 zxa and leaf 二分 树形dp
zxa and leaf 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5682 Description zxa have an unrooted t ...
- HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...
随机推荐
- oracle的分析函数over
参考地址:https://www.cnblogs.com/chinas/p/7058771.html?utm_source=itdadao&utm_medium=referral#_lab2_ ...
- HTML5 表单提交实例
html <!DOCTYPE html> <html> <head> <title>表单</title> <meta charset= ...
- bzoj4145 [AMPPZ2014]The Prices 状压 DP
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4145 题解 好像这道题有不少方法呢. ...谁叫这道题有点简单,所以方法多呗. 我的方法: 求 ...
- python2和python3的编码encode解码decode函数
python比较坑的一个点:意义完全变了的两个函数 首先 常用的编码方式有3种,utf-8: 常用的传输和存储格式,Unicode的一种简化 Unicode:包括了所有可能字符的国际统一编码 GBK ...
- leetcode-15双周赛-1289-下降路径最小和
题目描述: 方法一:动态规划 O(N^3) class Solution: def minFallingPathSum(self, arr: List[List[int]]) -> int: n ...
- [CSP-S模拟测试]:Emotional Flutter(贪心)
题目传送门(内部题51) 输入格式 第一行一个整数$t$表示数据组数.每组数据的第一行有三个整数$s,k,n$.第二行有$n$个整数$A_1,A_2,...,A_n$,依次表示黑白条的长度. 输出格式 ...
- JavaScript 中的dispatchEvent是怎么用的
https://zhidao.baidu.com/question/1859896201945858587.html https://www.cnblogs.com/playerlife/archiv ...
- GH001 on github
remote: warning: GH001: Large files detected. You may want to try Git Large File Storage - https://g ...
- nRF51822 蓝牙低功耗和 2.4GHz 专利 SoC
DESCRIPTION nRF51822 是功能强大.高灵活性的多协议 SoC,非常适用于 Bluetooth® 低功耗和 2.4GHz 超低功耗无线应用. nRF51822 基于配备 256kB f ...
- gradle spring 配置解释
plugins { id 'java' id 'eclipse' id 'idea' # 统一springboot版本号 id 'org.springframework.boot' version ' ...