HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4126
Genghis Khan the Conqueror
Time Limit: 10000/5000 MS (Java/Others)Memory Limit: 327680/327680 K (Java/Others)
#### 问题描述
> Genghis Khan(成吉思汗)(1162-1227), also known by his birth name Temujin(铁木真) and temple name Taizu(元太祖), was the founder of the Mongol Empire and the greatest conqueror in Chinese history. After uniting many of the nomadic tribes on the Mongolian steppe, Genghis Khan founded a strong cavalry equipped by irony discipline, sabers and powder, and he became to the most fearsome conqueror in the history. He stretched the empire that resulted in the conquest of most of Eurasia. The following figure (origin: Wikipedia) shows the territory of Mongol Empire at that time.
> 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.
#### 输入
> There are no more than 20 test cases in the input.
> For each test case, the first line contains two integers N and M (1
> The next line contains an integer Q (1 For each test case, output a real number demonstrating the expected minimal total cost. The result should be rounded to 4 digits after decimal point.
####样例输入
> 3 3
> 0 1 3
> 0 2 2
> 1 2 5
> 3
> 0 2 3
> 1 2 6
> 0 1 6
> 0 0
样例输出
6.0000
题意
给你一个无相图,要你求最小生成树,现在有q个查询,每个查询会改变一条边的权值,然后再改回去,要你求出每种情况下的最小生成树,最后求一下平均。
题解
1、如果改变的边不在我们一开始求的mst上,那么答案就是mst。
2、否则,把指定的树边删了,我们得到两个顶点集,那么代替原先那条边的一定是这两个集合的最短距离。所以我们只要处理出best[u][v](既u所在的集合和v所在的集合的最短距离)就能处理第2种情况了。做法是两次树dp,具体看代码。dp[u][v]:顶点u到集合v的最短距离。
best[u][v]:集合u到集合v的最短距离。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=3030;
struct Edge {
int u,v,w;
Edge(int u,int v,int w):u(u),v(v),w(w) {}
Edge() {}
bool operator < (const Edge& tmp) const {
return w<tmp.w;
}
} egs[maxn*maxn];
int n,m;
int G[maxn][maxn],dp[maxn][maxn],best[maxn][maxn];
bool used[maxn][maxn];
VPII tre[maxn];
int fa[maxn];
int find(int x) {
return fa[x]=fa[x]==x?x:find(fa[x]);
}
void dfs(int u,int fa,int rt) {
if(u!=rt&&!used[u][rt]) dp[rt][u]=min(dp[rt][u],G[rt][u]);
rep(i,0,tre[u].sz()) {
int v=tre[u][i].X;
if(v==fa) continue;
dfs(v,u,rt);
dp[rt][u]=min(dp[rt][u],dp[rt][v]);
}
}
int dfs2(int u,int fa,int rt) {
if(best[u][rt]<100000000) return best[u][rt];
best[u][rt]=min(best[u][rt],dp[u][rt]);
for(int i=0; i<tre[u].sz(); i++) {
int v=tre[u][i].X;
if(v==fa) continue;
dfs2(v,u,rt);
best[u][rt]=min(best[u][rt],best[v][rt]);
}
return best[u][rt];
}
///最小生成树
double kruskal() {
sort(egs,egs+m);
double mst=0;
for(int i=0; i<m; i++) {
int u=egs[i].u,v=egs[i].v,w=egs[i].w;
int pu=find(u);
int pv=find(v);
if(pu!=pv) {
fa[pv]=pu;
tre[u].pb(mkp(v,w));
tre[v].pb(mkp(u,w));
used[u][v]=used[v][u]=1;
mst+=w;
}
}
return mst;
}
void init() {
clr(G,0x3f);
clr(dp,0x3f);
clr(best,0x3f);
clr(used,0);
for(int i=0; i<n; i++) fa[i]=i,tre[i].clear();
}
int main() {
while(scf("%d%d",&n,&m)==2&&n) {
init();
for(int i=0; i<m; i++) {
int u,v,w;
scf("%d%d%d",&u,&v,&w);
G[u][v]=G[v][u]=w;
egs[i]=Edge(u,v,w);
}
double mst=kruskal();
///树形dp,dp[u][v]表示u到以v为根的子树的最短距离,既点到集合的距离(以u为根开始遍历,且只用非树边更新)
for(int i=0; i<n; i++) dfs(i,-1,i);
///记忆化搜索,best[u][v]表示以u为根的子树和以v为根的子树之间的最短距离,既集合到集合的距离
///对于子树v,我们已经求出了所有的点u到它的最短距离,现在只要遍历所有的u,求出最小值即可。
for(int i=0; i<n; i++) {
for(int j=0; j<tre[i].sz(); j++) {
int v=tre[i][j].X;
best[i][v]=best[v][i]=dfs2(i,v,v);
}
}
int q;
scf("%d",&q);
double ans=0;
rep(i,0,q) {
int u,v,w;
scf("%d%d%d",&u,&v,&w);
if(used[u][v]) {
///在树边上
ans+=mst-G[u][v]+min(w,best[u][v]);
} else {
///不在树边上
ans+=mst;
}
}
prf("%.4lf\n",ans/q);
}
return 0;
}
//end-----------------------------------------------------------------------
HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp的更多相关文章
- HDU 4126 Genghis Khan the Conqueror MST+树形dp
题意: 给定n个点m条边的无向图. 以下m行给出边和边权 以下Q个询问. Q行每行给出一条边(一定是m条边中的一条) 表示改动边权. (数据保证改动后的边权比原先的边权大) 问:改动后的最小生成树的权 ...
- 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条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边 (可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个 ...
- UVA- 1504 - Genghis Khan the Conqueror(最小生成树-好题)
题意: n个点,m个边,然后给出m条边的顶点和权值,其次是q次替换,每次替换一条边,给出每次替换的边的顶点和权值,然后求出这次替换的最小生成树的值; 最后要你输出:q次替换的平均值.其中n<30 ...
- hdu4126Genghis Khan the ConquerorGenghis Khan the Conqueror(MST+树形DP)
题目请戳这里 题目大意:给n个点,m条边,每条边权值c,现在要使这n个点连通.现在已知某条边要发生突变,再给q个三元组,每个三元组(a,b,c),(a,b)表示图中可能发生突变的边,该边一定是图中的边 ...
- HDU4126Genghis Khan the Conqueror(最小生成树+并查集)
Genghis Khan the Conqueror Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 327680/327680 K ...
- 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(元 ...
- Install Air Conditioning HDU - 4756(最小生成树+树形dp)
Install Air Conditioning HDU - 4756 题意是要让n-1间宿舍和发电站相连 也就是连通嘛 最小生成树板子一套 但是还有个限制条件 就是其中有两个宿舍是不能连着的 要求所 ...
随机推荐
- Verilog 位拼接运算符的优先级
最近研究FIFO的时候,在开源工程中看到这样一段代码 ; always @(posedge rd_clk) {'b0}}; else {'b0}}; else if(re) rp_bin <= ...
- springboot快速入门(二)——项目属性配置(日志详解)
一.概述 application.properties就是springboot的属性配置文件 在使用spring boot过程中,可以发现项目中只需要极少的配置就能完成相应的功能,这归功于spring ...
- 模拟UNIX(linux)文件系统
操作系统课程设计 一.实验内容 1. 题目:模拟UNIX(linux)文件系统 [问题描述] 在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的 模拟U ...
- 「功能笔记」Linux常用Shell命令(终端命令)备忘录
长期更新,空置.缺漏的部分会逐渐补上.未指明时,均为GNU版本. 文件命令 基础操作 ls 默认显示非隐藏文件.以文件名进行排序.文件名有颜色(蓝色文件夹.白色一般文件.绿色可执行文件). Cheat ...
- Jmeter 数据库配置池设置IP为参数
我在网上查了很多资料,发现jmter链接数据库的URL都是设置成固定值的.没有参数化. 当我需要使用配置文件链接不同服务器上的数据库的时候,发现无法实现. 原因在于:jmeter的元件执行优先级是配置 ...
- 通过ftp同步服务器文件:遍历文件夹所有文件(含子文件夹、进度条);简单http同步服务器文件实例
该代码主要实现,指定ftp服务地址,遍历下载该地址下所有文件(含子文件夹下文件),并提供进度条显示:另外附带有通过http地址方式获取服务器文件的简单实例 废话不多说,直接上代码: 1.FTPHelp ...
- SpringCloud 学习(二)-1 :服务注册与发现Eureka扩展
上一篇介绍了Eureka Server的搭建跟配置.Eureka Client的搭建跟配置.服务间通过服务名调用等,还有几个实际实验中遇到的问题及处理方案,本篇来玩一下Eureka的其他配置. 上一篇 ...
- 六度空间(MOOC)
六度空间: “六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论.这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五 ...
- leetcode刷题笔记191 位1的个数
题目描述: 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量). 示例: 输入: 输出: 解释: 32位整数 的二进制表示为 . 题目分析: 判断3 ...
- .NetCore mvc Ajax Post数据到后端
在前端页面中,如果没有表单,想把复杂对象提交到后端,可使用以下方法 后端Controller中定义以下方法: [HttpPost] public int AddSolution([FromBody]S ...