【Uvalive 5834】 Genghis Khan the Conqueror (生成树,最优替代边)
【题意】
一个N个点的无向图,先生成一棵最小生成树,然后给你Q次询问,每次询问都是x,y,z的形式, 表示的意思是在原图中将x,y之间的边增大(一定是变大的)到z时,此时最小生成数的值是多少。最后求Q次询问最小生成树的平均值。 N<=3000 , Q<=10000
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 xi
, yi and ci (ci ≤ 107
), showing that there
is a bidirectional road between xi and yi
, while the cost of setting up guarders on this road is ci
. We
guarantee that the graph is connected. The total cost of the graph is less or equal to 109
.
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 Xi
, Yi and Ci showing that
the cost of road (Xi
, Yi) may change to Ci (Ci ≤ 107
). We guarantee that the road always exists and
Ci
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.
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.
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
【分析】
WC这题做了我一整天!!!
哭了!!!!
死在所谓的树形DP上面了,啊啊啊啊啊,好垃圾啊。。
我真的觉得这个TreeDP挺难搞的,虽然不难想,但是实现起来真的各种bug。。
还是看了别人的题解才打出来TAT。。
正题->_->
这题的关键是在求出最小生成树之后求出去掉生成树任意一条边后剩下的两颗树的距离,可以证明这个距离就是最佳替换边的长度,而把原来最小生成树的边换成最佳替换边后所得到的生成树就是原图中去掉那条边的最小生成树,这个用反证法可以证明,如果新得到的树不是最小生成树可以推出原来的树也不是最小生成树。
那么就是看一看是要用最小替换边,还是直接修改当前的边的值了。
问题就是求最小替换边,用TreeDP实现。
1. 用S1[i][j]表示树A中的点i 到 树B(j点所在的树)的最近距离,这个过程可以在一边dfs就可以出来,对于每个 i 的dfs 复杂度是O(n) ,外加一个n的循环求出每个点,这里的总复杂度为 O(n^2)。
2. 通过求出来的S1[i][j] 再用一个dfs 求出 树B 到 树A的最近距离,(方法:枚举树A中的所有点 到 树B的最近距离,取其中的最小值。)显然, 这个求出来的值是我们要的最小替代边,把它保存到一个ANS[i][j]数组里面,(best[i][j]表示去掉边<i,j>后它的最小替代边的值)这里的总复杂度为 O(n^2)。
打法好高级,主要是不能算上删掉的边,而其他的都要算上,这里挺难搞的。。
看图吧,看图好懂一点。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 3010
#define INF 0xfffffff int dis[Maxn][Maxn]; struct node
{
int x,y,c,next;
}tt[Maxn*Maxn],t[*Maxn]; bool cmp(node x,node y) {return x.c<y.c;} int mymin(int x,int y) {return x<y?x:y;}
int mymax(int x,int y) {return x>y?x:y;}
int n,m; int fa[Maxn];
int ffa(int x)
{
if(fa[x]!=x) fa[x]=ffa(fa[x]);
return fa[x];
} int first[Maxn],len;
void ins(int x,int y,int c)
{
t[++len].x=x;t[len].y=y;t[len].c=c;
t[len].next=first[x];first[x]=len;
} int s1[Maxn][Maxn],ff[Maxn];
int dfs(int x,int f,int rt)
{
s1[rt][x]=INF;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
{
int y=t[i].y;
s1[rt][x]=mymin(s1[rt][x],dfs(y,x,rt));
}
if(f!=rt) s1[rt][x]=mymin(s1[rt][x],dis[rt][x]);
return s1[rt][x];
} bool in[Maxn][Maxn];
int ffind(int x,int f,int rt)
{
int now=s1[x][rt];
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
{
int y=t[i].y;
now=mymin(now,ffind(y,x,rt));
}
return now;
} int ans[Maxn][Maxn];
int sum;
void init()
{
memset(dis,,sizeof(dis));
for(int i=;i<=m;i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
x++;y++;
tt[i].x=x;tt[i].y=y;tt[i].c=c;
dis[x][y]=dis[y][x]=c;
}
//kruskal
sort(tt+,tt++m,cmp);
for(int i=;i<=n;i++) fa[i]=i;
int cnt=;
len=;sum=;
memset(first,,sizeof(first));
// memset(ans,63,sizeof(ans));
for(int i=;i<=m;i++)
{
if(ffa(tt[i].x)!=ffa(tt[i].y))
{
fa[ffa(tt[i].x)]=ffa(tt[i].y);
ins(tt[i].x,tt[i].y,tt[i].c);
ins(tt[i].y,tt[i].x,tt[i].c);
cnt++;
sum+=tt[i].c;
}
if(cnt==n-) break;
}
} void query()
{
int q;
double fans=;
scanf("%d",&q);
for(int i=;i<=q;i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
x++;y++;
if(in[x][y]) fans+=1.0*mymin(sum+c-dis[x][y],sum+ans[x][y]-dis[x][y]);
else fans+=1.0*sum;
}
printf("%.4lf\n",fans*1.0/q);
} int main()
{
while()
{
scanf("%d%d",&n,&m);
if(n==&&m==) break;
init();
for(int i=;i<=n;i++) dfs(i,,i);
memset(ans,,sizeof(ans));
memset(in,,sizeof(in));
for(int i=;i<=n;i++)
{
for(int j=first[i];j;j=t[j].next)
{
int y=t[j].y;
ans[i][y]=ans[y][i]=mymin(ans[i][y],ffind(y,i,i));
in[i][y]=in[y][i]=;
}
}
query();
}
return ;
}
2016-11-02 20:40:32
哭了====再做一道k度限制生成树就不做了TAT。。
【Uvalive 5834】 Genghis Khan the Conqueror (生成树,最优替代边)的更多相关文章
- uvalive 5834 Genghis Khan The Conqueror
题意: 给出一个图,边是有向的,现在给出一些边的变化的信息(权值大于原本的),问经过这些变换后,MST总权值的期望,假设每次变换的概率是相等的. 思路: 每次变换的概率相等,那么就是求算术平均. 首先 ...
- HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 Genghis Khan the Conqueror Time Limit: 10000/50 ...
- 刷题总结——Genghis Khan the Conqueror (hdu4126)
题目: Genghis Khan(成吉思汗)(1162-1227), also known by his birth name Temujin(铁木真) and temple name Taizu(元 ...
- UVA- 1504 - Genghis Khan the Conqueror(最小生成树-好题)
题意: n个点,m个边,然后给出m条边的顶点和权值,其次是q次替换,每次替换一条边,给出每次替换的边的顶点和权值,然后求出这次替换的最小生成树的值; 最后要你输出:q次替换的平均值.其中n<30 ...
- HDU 4126 Genghis Khan the Conqueror MST+树形dp
题意: 给定n个点m条边的无向图. 以下m行给出边和边权 以下Q个询问. Q行每行给出一条边(一定是m条边中的一条) 表示改动边权. (数据保证改动后的边权比原先的边权大) 问:改动后的最小生成树的权 ...
- HDU 4126 Genghis Khan the Conqueror (树形DP+MST)
题意:给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边 (可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个 ...
- 「日常训练」 Genghis Khan the Conqueror(HDU-4126)
题意 给定\(n\)个点和\(m\)条无向边(\(n\le 3000\)),需要将这\(n\)个点连通.但是有\(Q\)次(\(Q\le 10^4\))等概率的破坏,每次破坏会把\(m\)条边中的某条 ...
- HDU-4126 Genghis Khan the Conqueror 树形DP+MST (好题)
题意:给出一个n个点m条边的无向边,q次询问每次询问把一条边权值增大后问新的MST是多少,输出Sum(MST)/q. 解法:一开始想的是破圈法,后来想了想应该不行,破圈法应该只能用于加边的情况而不是修 ...
- HDU4126Genghis Khan the Conqueror(最小生成树+并查集)
Genghis Khan the Conqueror Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 327680/327680 K ...
随机推荐
- KindEditor 修改多图片上传显示限制大小和张数
在使用KindEditor的时候用到多图片上传时,提示有最多上传20张图片,单张图片容量不超过1MB: 修改的文件的地方在:kindeditor\plugins\multiimage\multiima ...
- jQuery滑过头像图片展示个人信息效果
这是一款经典的jQuery图片插件,同时,也可以是一款jQuery提示框插件.这款jQuery插件的功能是当你把鼠标滑过头像图片缩略图时,即可弹出头像对应用户的详细个人信息,弹出的标签虽然不大,但是还 ...
- A Swift Tour(3) - Functions and Closures
Functions and Closures 使用func来声明函数,通过括号参数列表的方式来调用函数,用 --> 来分割函数的返回类型,参数名和类型,例如: func greet(name: ...
- MVC小系列(十八)【给checkbox和radiobutton添加集合的重载】
mvc对DropDownListFor的重载很多,但对checkbox和radiobutton没有对集合的重载 所以该讲主要针对集合的扩展: #region 复选框扩展 /// <summary ...
- Dapper.NET - ORM(ibatis.Net)
Dapper.NET使用 1.为什么选择Dapper 2.以Dapper(4.0)为例. 2.1 在数据库中建立几张表. 2.2实体类. 3.使用方法 3.1 一对一映射 3.2 一对多映射 3.3 ...
- js一些算法实现
1.约瑟夫环实现 //附有调试 function joseph(n,p){ var arr=[]; for(var i=0;i<n;i++){ arr.push(i); } debugger; ...
- 安装aptana插件报Error opening the editor. java.lang.NullPointerException
Aptana的官方网站下载eclipse的插件: http://update.aptana.com/update/studio/3.2/ ,可以在线安装也可以下载插件后再安装,我是以在线的形式安装的 ...
- Codevs 3729 飞扬的小鸟
飞扬的小鸟 标签 动态规划 NOIp提高组 2014 难度 提高+/省选- 题目描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小 ...
- centOS 6 python MySQLdb 提示 no module
http://www.cnblogs.com/czh-liyu/archive/2012/11/30/2796028.html(转) 用python连接本地数据库时,提示no module MySQL ...
- linux扩展lvm磁盘
env: centos 6.5 x64 hyper-v虚拟机 这个方法可以在当前运行的系统中扩展root磁盘 详细步骤 之前想创建的一个虚拟机的磁盘空间不够用了,所以想扩容一下磁盘. 正好使用的时候是 ...