题目链接


题目大意:

给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边(可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个点相互连通的最小花费的期望。


解题思路:

对于每次询问, 都是将a,b之间的边增加到c, 会出现 两种情况:

  1. 如果边权增加的那条边原先就不在最小生成树中,那么这时候的最小生成树的值不变

  2. 如果该边在原最小生成树中,那么这时候将增加的边从原最小生成树中去掉,这时候生成树就被分成了两个各自联通的部分,可以证明的是,这时候的最小生成树一定是将这两部分联通起来的最小的那条边。

因为询问很多我们怎么快速求出删除一条生成树上的边之后,快速找到非树边里面的最小的一条边?

解法:我们把一个点uuu固定为根,然后这个树的结构久定型了!那么我们久可以用(v,u)[fa[v]!=u](v,u)[fa[v]!=u](v,u)[fa[v]!=u]去自底向上跟新!这样可以保证所以的非树边都可以枚举到,并且跟新所以的情况

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 9e6 + 10, mod = 1e9 + 9;
const int maxn = 3010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x)
{x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args)
{read(first);read(args...);
}
struct Edge {int u,v,w;bool operator < (const Edge & a) const {return w < a.w;}
}edge[N];
int n, m;
bool vis[maxn][maxn];
int mp[maxn][maxn], dp[maxn][maxn];
vector<int> G[maxn];
int fa[maxn];
int find(int x) {return fa[x] == x ? x : fa[x] = find(fa[x]);
}
inline int kru() {int sum = 0;sort(edge,edge+m);for(int i = 0; i < m; ++ i) {int u = edge[i].u, v = edge[i].v, w = edge[i].w;int fu = find(u), fv = find(v);if(fu != fv) {fa[fv] = fu;G[v].push_back(u);G[u].push_back(v);// 建立最小生成树vis[v][u] = vis[u][v] = 1;sum += w;}}return sum;
}inline int dfs(int root, int u, int fa) {int ans = INF;for(auto it : G[u]) {if(it == fa) continue;int minv = dfs(root,it,u);ans = min(minv,ans);dp[u][it] = dp[it][u] = min(dp[u][it],minv);//自底向上跟新}if(fa != root) ans = min(ans,mp[root][u]);//所以的非树边return ans;
} int main() {IOS;while(cin >> n >> m && n) {for(int i = 0; i < n; ++ i)for(int j = 0; j < n; ++ j)mp[i][j] = INF, dp[i][j] = INF, vis[i][j] = 0;for(int i = 0; i < n; ++ i) G[i].clear(), fa[i] = i;for(int i = 0; i < m; ++ i) {int u, v, w;cin >> u >> v >> w;mp[u][v] = mp[v][u] = w;edge[i] = {u,v,w};}int ans = kru();//最小生成树for(int i = 0; i < n; ++ i) dfs(i,i,-1);int q;cin >> q;double sum = 0;for(int i = 1; i <= q; ++ i) {int u, v, w;cin >> u >> v >> w;if(!vis[u][v]) sum += ans;else sum = sum + ans - mp[u][v] + min(dp[u][v],w);// cout << sum << endl;}cout << fixed << setprecision(4) << sum / (double)q << endl;}
}

图论500题 ---- 并查集+树形dp+枚举 求解动态的最小生成树 HDU 4126相关推荐

  1. 图论500题 ---- 并查集求路径上最大值最小不超过K的点对数 HDU Portal

    题目链接 题目大意: 就给你一个图,qqq次询问,问你这个图上有多少对点之间的所以路径上的最大值的最小值不超过kkk? 解题思路: 首先我们知道这本质上就是求两个点联通的路径上的最大值最小是多少? 那 ...

  2. HDU 5575 Discover Water Tank 并查集 树形DP

    题意: 有一个水槽,边界的两块板是无穷高的,中间有n-1块隔板(有高度),现有一些条件(i,y,k),表示从左到右数的第i列中,在高度为(y+0.5)的地方是否有水(有水:k = 1),问最多能同时满 ...

  3. bzoj4144 [AMPPZ2014]Petrol 图论 最短路 并查集

    bzoj4144 [AMPPZ2014]Petrol 图论 最短路 并查集 1.这道题我们主要就是要求出距离一个油站的最近的油站 首先我们dijkstra 求出任意一个点到 离他最近的油站的距离 2. ...

  4. 【转载】图论 500题——主要为hdu/poj/zoj

    转自--http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  5. 雷神领域(并查集真是个好东西)并查集+流氓dp

    考场上,整整看了半个小时以上的题目!!! 化简题意: 给定一个全0矩阵,一些坐标点(x,y)为1,当三个点可以构成一个直角三角形时(直角边长为整数)拓展为一个矩形,之后从(0,0)出发,求最多的占用行 ...

  6. C - BLG POJ - 1417 种类并查集加dp(背包)

    思路:刚看这道题感觉什么都不清楚,人物之间的关系一点也看不出来,都不知道怎么写,连并查集都没看出来,但是你可以仔细分析一下,当输入字符串为"yes"的时候,我们设输入的值为x和y, ...

  7. 【BZOJ2728】[HNOI2012]与非 并查集+数位DP

    [BZOJ2728][HNOI2012]与非 Description Input 输入文件第一行是用空格隔开的四个正整数N,K,L和R,接下来的一行是N个非负整数A1,A2--AN,其含义如上所述.  ...

  8. 【图论】【并查集】矩形(ssl 1222)

    矩形 ssl 1222 题目大意: 有n个矩阵,现在将有重叠部分的两个矩阵合并成一个图形,问有多少个图形 原题: 题目描述 在一个平面上有n个矩形.每个矩形的边都平行于坐标轴并且都具有值为整数的顶点. ...

  9. C#LeetCode刷题-并查集

    并查集篇 # 题名 刷题 通过率 难度 128 最长连续序列 39.3% 困难 130 被围绕的区域 30.5% 中等 200 岛屿的个数 38.4% 中等 547 朋友圈 45.1% 中等 684 ...

最新文章

  1. RTX 3090的深度学习环境配置指南:Pytorch、TensorFlow、Keras
  2. 365天里有300天都想辞职,换个公司,你的2019会更好吗?
  3. CentOS虚拟机不能联网状况下yum方式从本地安装软件包
  4. 【Linux】Makefile文件
  5. SAP BSP, Java Web Project,Android和微信小程序的初始页面设置
  6. 如何用 Python 实现超级玛丽的人物行走和碰撞检测?
  7. 业界资讯:adobe creative suite 5.5你准备好了吗?
  8. 欧拉函数、欧拉定理、费马小定理(附例题)
  9. 在阿里云开源镜像站中下载centOS7
  10. css动画钟表——transform之rotate
  11. 可逆矩阵性质总结_逆矩阵的定义与性质.doc
  12. 汉子转五笔SQL脚本函数
  13. CSS实现文字凹凸效果
  14. python精灵和精灵组_Pygame精灵和精灵组
  15. Linux I2C驱动
  16. python easydict 简单使用
  17. 芯科发布EFR32BG22芯片,强劲性能对比TI芯片CC2640R2F和CC2640R2L
  18. 【面经攒人品】蚂蚁金服—反洗钱岗
  19. 离线识别率高达99%的Python人脸识别系统,开源~
  20. Leetcode刷题总结和心得(5)

热门文章

  1. 哔哩哔哩小甲鱼 汇编语言 记录一下 寄存器(内存访问)两个小实验
  2. Windows如何 cmd 查找文件路径 开机启动 CMD语音播放 CMD切换到管理员!
  3. squid与varnish
  4. 浅析 Node.js 的 vm 模块以及运行不信任代码
  5. sys.stdout.write与sys.sterr.write(二)
  6. openstack网络服务neutron
  7. 第九天:基础文件管理
  8. 《ASCE1885的源码分析》の跨平台互斥对象Mutex封装类
  9. hive 中文comment乱码解决
  10. pandas dataframe 表头_python_库_pandas