题目:

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.

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 ;
}

最新文章

  1. eclipse关闭编译时不必要的校验
  2. Jquery Mobile开发以及Js对象动态绑定
  3. 读取ini配置文件
  4. poj 3580 SuperMemo
  5. C# 文件管理类 Directory
  6. OpenCV入门学习笔记
  7. myeclipse开发代码颜色搭配保护视力
  8. ASP.NET 安全认证
  9. ASP.NET实现列表页连接查询 拼接sql语句 绑定grivdView
  10. 亚马逊记AWS(Amazon Web Services)自由EC2应用
  11. Excel教程(7) - 工程函数
  12. 腾讯云数据库团队:PostgreSQL TOAST技术理解
  13. ●HDU 3507 Print Article
  14. SuperMap iObject入门开发系列之六管线区域查询
  15. 【Loadrunner_WebService接口】对项目中的GetProduct接口生成性能脚本
  16. DOM节点的增删改查以及class属性的操作
  17. 线段树-&gt;面积并 Atlantis HDU - 1542
  18. IO流程及优化
  19. HTML5 Canvas ( 线段的绘制 ) beginPath, moveTo, strokeStyle, stroke
  20. python subprocess 和 multiprocess选择以及我遇到的坑

热门文章

  1. 告诉你今年是哪个生肖年的java程序
  2. 已解决: mybatis报错 org.apache.ibatis.reflection.ReflectionException: There is no getter for property named &#39;xxx&#39; in &#39;class java.lang.String&#39;
  3. vue学习之路 - 2.基本操作(上)
  4. 对比传统方式访问数据库和SpringData访问数据库
  5. 【PHP】$_SERVER整理
  6. 5904.刺客信条(AC)
  7. CSAPP 缓冲区溢出试验
  8. Windows下安装配置SQLite和使用的教程
  9. Gym - 101128F Landscaping(网络流)
  10. OWINS是什么(转载)