题意:

n个点,m个边,然后给出m条边的顶点和权值,其次是q次替换,每次替换一条边,给出每次替换的边的顶点和权值,然后求出这次替换的最小生成树的值;

最后要你输出:q次替换的平均值。其中n<3000,q<10000。

分析:

我们可以先求最小生成树,对于最小生成树的每一条边,我们要找到它的最佳替代边,使其价值最小。

具体实践方法:

树形dp,从每个点dfs一次,每次把i当成根,其余都是它的孩子,更新dp数组,对于i点为根的除j之外的所有的

子树中的所有点到j距离最小值。每次从一个点root开始dfs,搜索到最后一个叶子,开始看G[root][u]的大小,保证(root,u)

不是MST上的的边,那么一路返回,连接叶子节点的那条边的最佳替换边就是G[root][u]的大小,再继续返回,

此过程要看,map[root][...]的大小,其中[...]表示从叶子节点一路返回过来的点。

// File Name: 1504.cpp
// Author: Zlbing
// Created Time: 2013/6/17 19:36:53 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--) const int MAXN=;
struct Edge{
int u,v,cost;
bool operator <(const Edge &rsh)const{
return cost<rsh.cost;
}
};
vector<Edge>edges;
vector<int> mst[MAXN];
int gmst[MAXN][MAXN];
int f[MAXN];
int dp[MAXN][MAXN];
int G[MAXN][MAXN];
int n,m,Q;
int ans=;
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
void kruscal()
{
ans=;
CL(gmst,);
for(int i=;i<=n;i++)f[i]=i;
for(int i=;i<m;i++)
{
Edge e=edges[i];
int fu=find(e.u);
int fv=find(e.v);
if(fu!=fv)
{
ans+=e.cost;
f[fu]=fv;
mst[e.u].push_back(e.v);
mst[e.v].push_back(e.u);
gmst[e.u][e.v]=gmst[e.v][e.u]=;
}
}
}
int dfs(int root,int u,int fa)
{
int s=INF;
for(int i=;i<mst[u].size();i++)
{
int v=mst[u][i];
if(v==fa)continue;
int tmp=dfs(root,v,u);
s=min(s,tmp);
dp[u][v]=dp[v][u]=min(dp[u][v],tmp);
}
if(root!=fa)//保证这条边不是生成树的边
s=min(s,G[root][u]);
return s;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==)break;
edges.clear();
int a,b,c;
REP(i,,n)mst[i].clear();
for(int i=;i<n;i++)
for(int j=;j<n;j++)
{
dp[i][j]=INF;
G[i][j]=INF;
}
REP(i,,m)
{
scanf("%d%d%d",&a,&b,&c);
edges.push_back((Edge){a,b,c});
G[a][b]=G[b][a]=c;
}
sort(edges.begin(),edges.end());
kruscal();
REP(i,,n-)
dfs(i,i,-);
int sum=;
scanf("%d",&Q);
REP(i,,Q)
{
scanf("%d%d%d",&a,&b,&c);
if(!gmst[a][b])
sum+=ans;
else
sum+=ans*1.0-G[a][b]+min(dp[a][b],c);
}
double s=sum/(double)Q;
printf("%.4lf\n",s);
}
return ;
}

UVA- 1504 - Genghis Khan the Conqueror(最小生成树-好题)的更多相关文章

  1. HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 Genghis Khan the Conqueror Time Limit: 10000/50 ...

  2. HDU4126Genghis Khan the Conqueror(最小生成树+并查集)

    Genghis Khan the Conqueror Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 327680/327680 K ...

  3. 刷题总结——Genghis Khan the Conqueror (hdu4126)

    题目: Genghis Khan(成吉思汗)(1162-1227), also known by his birth name Temujin(铁木真) and temple name Taizu(元 ...

  4. hdu4126Genghis Khan the Conqueror (最小生成树+树形dp)

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others) Total Submiss ...

  5. 「日常训练」 Genghis Khan the Conqueror(HDU-4126)

    题意 给定\(n\)个点和\(m\)条无向边(\(n\le 3000\)),需要将这\(n\)个点连通.但是有\(Q\)次(\(Q\le 10^4\))等概率的破坏,每次破坏会把\(m\)条边中的某条 ...

  6. 【Uvalive 5834】 Genghis Khan the Conqueror (生成树,最优替代边)

    [题意] 一个N个点的无向图,先生成一棵最小生成树,然后给你Q次询问,每次询问都是x,y,z的形式, 表示的意思是在原图中将x,y之间的边增大(一定是变大的)到z时,此时最小生成数的值是多少.最后求Q ...

  7. HDU 4126 Genghis Khan the Conqueror MST+树形dp

    题意: 给定n个点m条边的无向图. 以下m行给出边和边权 以下Q个询问. Q行每行给出一条边(一定是m条边中的一条) 表示改动边权. (数据保证改动后的边权比原先的边权大) 问:改动后的最小生成树的权 ...

  8. uvalive 5834 Genghis Khan The Conqueror

    题意: 给出一个图,边是有向的,现在给出一些边的变化的信息(权值大于原本的),问经过这些变换后,MST总权值的期望,假设每次变换的概率是相等的. 思路: 每次变换的概率相等,那么就是求算术平均. 首先 ...

  9. HDU 4126 Genghis Khan the Conqueror (树形DP+MST)

    题意:给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边 (可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个 ...

随机推荐

  1. 零基础学习云计算及大数据DBA集群架构师【Linux系统环境及权限管理12.21-12.25】

    从这周开始Linux的学习,老师是一位女老师,这到给了更多的信心,老师讲得很快,如果说只谈记命令的话是不多,但是要真正去理解,其实内容还是挺多的,我都是以老师讲的内容为主线,然后自己再看鸟哥的书做加深 ...

  2. 基于JAVA网络编程的聊天小程序

    package com.neusoft.edu.socket; import java.io.BufferedReader; import java.io.IOException; import ja ...

  3. nodejs开发环境sublime配置

    前端时间使用webstorm搭建一个node.js的学习环境,感觉非常强大.不过由于其加载的速度,每次让都让我抓狂.后来我找到了一个sublime.虽说3.0以上是收费的,2.0暂时免费.官方的不对s ...

  4. CentOS 6.5 64位,调整分区大小

    调整硬盘分区大小 想增加root空间,减少home空间. 1.查看硬盘使用情况. [root@npm ~]# df -h Filesystem Size Used Avail Use% Mounted ...

  5. TSQL Beginners Challenge 1 - Find the second highest salary for each department

    很久以前准备写的系列文章,后来因为懒一直耽搁着,今天突然决定继续下去,于是有了这篇文章,很基础,但很常用.题目描述依然拷贝.简单来说就是找出个个部门薪水排名第二的人,排名相同的要一起列出来. Intr ...

  6. 受限玻尔兹曼机(RBM)

    能量模型 RBM用到了能量模型. 简单的概括一下能量模型.假设一个孤立系统(总能量$E$一定,粒子个数$N$一定),温度恒定为1,每个粒子有$m$个可能的状态,每个状态对应一个能量$e_i$.那么,在 ...

  7. I/O多路复用之poll

    poll函数和select函数非常相似,但是函数接口不一样. #include <poll.h> int poll(struct pollfd *fdarray, unsigned lon ...

  8. css3基础教程十六变形与动画animation

    前面我们讲过的变形与动画一般都是通过鼠标的单击.获得焦点,被点击或对元素进行一定改变后以后触发效果的,那么有没有像Flash一样自动播放的动画效果呢?答案当然是肯定的,这就是我们今天要讲到的anima ...

  9. 用连接池提高Servlet访问数据库的效率

    Java Servlet作为首选的服务器端数据处理技术,正在迅速取代CGI脚本.Servlet超越CGI的优势之一在于,不仅多个请求可以共享公用资源,而且还可以在不同用户请求之间保留持续数据.本文介绍 ...

  10. Float之谜

    先来看几个例子: public class Thirtyfirst1{ public static void main(String[] args){ int i = 2000000000; int ...