刷题总结——Genghis Khan the Conqueror (hdu4126)
题目:
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.
Input
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<=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.
Output
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.
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.
题解:
很好的一道树形dp题··
每个询问x,y其实求的就是相邻的两个子树x,y的最短距离··我们用best[x][y]表示
由于q很大··上述值肯定是通过预处理求出···首先求出最开始的最小生成树,接着我们要先求得f[i][j],表示以i为根节点,通过非生成树边到达j所在子树的最短距离···对此我们一一枚举0——n-1作为根节点然后树形dp即可求得···
求完f[i][j]的话best[x][y]就很简单了··我们只需枚举y所在子树的所有节点u··求出f[u][x]的最小值即可··最后再与新的增大的边c比较一下取最小值就可以了
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<cctype>
#include<algorithm>
using namespace std;
const int N=;
const int M=9e6+;
const int inf=0x3f3f3f3f;
inline int R()
{
char c;int f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar()) f=(f<<)+(f<<)+c-'';
return f;
}
struct node
{
int a,b,val;
}ed[M];
int n,m,q,fst[N],nxt[N*],go[N*],val[N*],tot,father[N],map[N][N],f[N][N],best[N][N];
double sum=,ans=;
bool jud[N][N];
inline int get(int a)
{
if(father[a]==a) return a;
else return father[a]=get(father[a]);
}
inline bool cmp(node a,node b)
{
return a.val<b.val;
}
inline void comb(int a,int b,int c)
{
nxt[++tot]=fst[a],fst[a]=tot,go[tot]=b,val[tot]=c;
nxt[++tot]=fst[b],fst[b]=tot,go[tot]=a,val[tot]=c;
}
inline void pre()
{
tot=;ans=sum=;
for(int i=;i<n;i++) father[i]=i;
memset(fst,,sizeof(fst));memset(map,inf,sizeof(map));
memset(f,inf,sizeof(f));memset(jud,false,sizeof(jud));
memset(best,inf,sizeof(best));
}
inline int dfs1(int u,int fa,int rt)
{
for(int e=fst[u];e;e=nxt[e])
{
int v=go[e];if(v==fa) continue;
f[rt][u]=min(f[rt][u],dfs1(v,u,rt));
}
if(fa!=rt) f[rt][u]=min(f[rt][u],map[rt][u]);
return f[rt][u];
}
inline int dfs2(int u,int fa,int rt)
{
int ans=f[u][rt];
for(int e=fst[u];e;e=nxt[e])
{
int v=go[e];if(v==fa) continue;
ans=min(ans,dfs2(v,u,rt));
}
return ans;
}
inline void dp()
{
for(int i=;i<n;i++)
dfs1(i,-,i);
for(int i=;i<n;i++)
for(int e=fst[i];e;e=nxt[e])
{
int v=go[e];best[i][v]=best[v][i]=dfs2(v,i,i);
}
}
int main()
{
// freopen("a.in","r",stdin);
while(~scanf("%d%d",&n,&m)&&(n+m))
{
int a,b,c;pre();
for(int i=;i<=m;i++)
{
a=R(),b=R(),c=R();map[a][b]=map[b][a]=c;
ed[i].a=a,ed[i].b=b,ed[i].val=c;
}
sort(ed+,ed+m+,cmp);int temp=;
for(int i=;i<=m;i++)
{
int fa=get(ed[i].a),fb=get(ed[i].b);
if(fa!=fb)
{
sum+=ed[i].val;
father[fa]=fb;temp++;
comb(ed[i].a,ed[i].b,ed[i].val);
jud[ed[i].a][ed[i].b]=jud[ed[i].b][ed[i].a]=true;
}
if(temp==n-) break;
}
dp();
q=R();
for(int t=;t<=q;t++)
{
a=R(),b=R(),c=R();
if(!jud[a][b]) ans+=sum;
else
{
int temp=min(c,best[a][b]);
ans+=(sum-map[a][b]+temp);
}
}
ans=(double)ans/q;
printf("%0.4f\n",ans);
}
return ;
}
刷题总结——Genghis Khan the Conqueror (hdu4126)的更多相关文章
- 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 树形DP+MST (好题)
题意:给出一个n个点m条边的无向边,q次询问每次询问把一条边权值增大后问新的MST是多少,输出Sum(MST)/q. 解法:一开始想的是破圈法,后来想了想应该不行,破圈法应该只能用于加边的情况而不是修 ...
- 「日常训练」 Genghis Khan the Conqueror(HDU-4126)
题意 给定\(n\)个点和\(m\)条无向边(\(n\le 3000\)),需要将这\(n\)个点连通.但是有\(Q\)次(\(Q\le 10^4\))等概率的破坏,每次破坏会把\(m\)条边中的某条 ...
- UVA- 1504 - Genghis Khan the Conqueror(最小生成树-好题)
题意: n个点,m个边,然后给出m条边的顶点和权值,其次是q次替换,每次替换一条边,给出每次替换的边的顶点和权值,然后求出这次替换的最小生成树的值; 最后要你输出:q次替换的平均值.其中n<30 ...
- 【Uvalive 5834】 Genghis Khan the Conqueror (生成树,最优替代边)
[题意] 一个N个点的无向图,先生成一棵最小生成树,然后给你Q次询问,每次询问都是x,y,z的形式, 表示的意思是在原图中将x,y之间的边增大(一定是变大的)到z时,此时最小生成数的值是多少.最后求Q ...
- HDU 4126 Genghis Khan the Conqueror MST+树形dp
题意: 给定n个点m条边的无向图. 以下m行给出边和边权 以下Q个询问. Q行每行给出一条边(一定是m条边中的一条) 表示改动边权. (数据保证改动后的边权比原先的边权大) 问:改动后的最小生成树的权 ...
- uvalive 5834 Genghis Khan The Conqueror
题意: 给出一个图,边是有向的,现在给出一些边的变化的信息(权值大于原本的),问经过这些变换后,MST总权值的期望,假设每次变换的概率是相等的. 思路: 每次变换的概率相等,那么就是求算术平均. 首先 ...
- HDU 4126 Genghis Khan the Conqueror (树形DP+MST)
题意:给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边 (可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个 ...
- HDU4126Genghis Khan the Conqueror(最小生成树+并查集)
Genghis Khan the Conqueror Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 327680/327680 K ...
随机推荐
- facebook的infer检测工具的安装
缘由 由于公司产出代码的时候会使用静态扫描工具检测代码的质量,所以自己就想动手尝试一番infer整个的使用方式和使用效果,便动手安装了infer,结果安装过程中遇见太多的坑,导致很多时候都安装失败,这 ...
- iOS 多线程(NSThread、GCD、NSOperation)
ios中得多线程技术主要使用3种:NSThread.NSOperation和GCD 一.NSThread: 最轻量级方法,但是不安全需要手动加锁,需要自己管理生命周期 NSThread的使用方法有2种 ...
- sql 参数化查询
在初次接触sql时,笔者使用的是通过字符串拼接的方法来进行sql查询,但这种方法有很多弊端 其中最为明显的便是导致了sql注入. 通过特殊字符的书写,可以使得原本正常的语句在sql数据库里可编译, ...
- 二 python并发编程之多进程-理论
一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的任务,写书的任 ...
- JavaScript算数
常数 Math.E 圆周率 Math.PI 2的平方根 ...
- jupyter notebook(二)——修改jupyter打开默认的工作目录
1.简述 jupyter notebook,启动后,浏览器发现工作目录并不是自己真正的代码的工作路径.所以需要设置一下.这样方便自己快捷使用. 2.设置修改jupyter notebook打开后默认工 ...
- 并查集:HDU5326-Work(并查集比较简单灵活的运用)
Work HDU原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=5326 Time Limit: 2000/1000 MS (Java/Others) M ...
- Spring Boot 开发系列一 开发踩坑
这是学习spring boot 的第二周,公司号称这玩意是啥都不会的新手就可以填空开发,于是决定上手一把,怎么说我也是搞了快七八年的.NET和.NETcore,没想到无情打脸,快被这个能填空开的IDE ...
- 随手正则写的 CSDN【只看楼主】功能
写这个的时候居然没有看到原来CSDN已经有这个功能了,写完代码了突然发现原来早就已经有了. 现把代码贴出来吧,虽然有很多解析HTML的开源类库如:http://htmlagilitypack.code ...
- js基础之javascript函数定义及种类-普通涵数-自执行函数-匿名函数
普通函数 1.不带参数 function fucname(){ alert("hello"); } funcname() 2.带参数 function funcname(arg){ ...