hdu4126(最小生成树最佳替换边)
来源:互联网 发布:数学软件有哪些 编辑:程序博客网 时间:2024/05/22 17:21
链接:点击打开链接
题意:给出一个无向图,有q次询问,每次更改一条边的距离,求出每次更改后的最小生成树的平均值
代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;int son[5005],dfs_sort[5005],dfs_num[5005];int n,id,sum,vis[5005],dis[5005],fa[5005],dp[5005][5005],G[5005][5005];int prim(int v){ int i,j,u,tmp; sum=0; for(i=1;i<=n;i++){ dis[i]=G[v][i]; vis[i]=0; } dis[v]=0,vis[v]=1; for(i=2;i<=n;i++){ tmp=INF; u=v; for(j=1;j<=n;j++) if(dis[j]<tmp&&vis[j]==0){ tmp=dis[j]; u=j; } sum+=tmp; vis[u]=1; for(j=1;j<=n;j++) if(G[u][j]<dis[j]&&vis[j]==0){ fa[j]=u; //因为边数比较多,因此用prim dis[j]=G[u][j]; //记录每个节点最小生成树上的父节点 } } return sum;}void dfs(int s){ int i; vis[s]=1; dfs_num[s]=id; dfs_sort[id++]=s; for(i=1;i<=n;i++){ if(fa[i]==s&&vis[i]==0){ //求出最小生成树上的dfs顺序 dfs(i); //和每个节点的儿子结点 son[s]+=son[i]; } }}int main(){ //更改一条边只可能有两种情况 int ans[3005]; //一个是这条边不在最小生成树上,则不用修改 int m,i,j,u,v,w,q,cnt,num1,num2; //另一个则是这条边在最小生成树上,则相当于 while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){ //求删除最小生成树上的边后将两个连通分量再 memset(G,INF,sizeof(G)); //重新连上所花的最短距离,可以通过dfs的顺序 for(i=1;i<=n;i++) //进行dp fa[i]=son[i]=1; fa[1]=-1; for(i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); u++,v++; G[u][v]=G[v][u]=w; //双向边 } memset(vis,0,sizeof(vis)); sum=prim(1); memset(vis,0,sizeof(vis)); id=1; dfs(1); memset(dp,INF,sizeof(dp)); for(i=1;i<=n;i++){ //dp[i][j]表示顺序是i的节点到以顺序是 for(j=1;j<=n;j++){ //j的节点作为根节点的子树的最短距离 num1=dfs_sort[i],num2=dfs_sort[j]; if(G[num1][num2]!=INF) if(fa[num1]!=num2&&fa[num2]!=num1) dp[i][j]=G[num1][num2]; } } for(i=1;i<=n;i++) for(j=n;j>=1;j--) dp[i][dfs_num[fa[dfs_sort[j]]]]=min(dp[i][dfs_num[fa[dfs_sort[j]]]],dp[i][j]); cnt=0; memset(ans,-1,sizeof(ans)); scanf("%d",&q); for(j=1;j<=q;j++){ scanf("%d%d%d",&u,&v,&w); u++,v++; if(fa[u]==v) //保证u在上 swap(u,v); if(fa[u]!=v&&fa[v]!=u) //不在直接加 cnt+=sum; else if(fa[v]==u&&ans[v]!=-1) cnt+=(sum-G[u][v]+min(w,ans[v])); else{ //求出u节点往上的节点与v所在的连通块 ans[v]=INF; //的最短距离 for(i=1;i<=n;i++){ if(dfs_num[i]<dfs_num[v]||dfs_num[i]>dfs_num[v]+son[v]-1) ans[v]=min(ans[v],dp[dfs_num[i]][dfs_num[v]]); else ans[v]=min(ans[v],dp[dfs_num[u]][dfs_num[v]]); }// cout<<ans[v]<<endl; cnt+=(sum-G[u][v]+min(w,ans[v])); }// cout<<cnt<<"<<<>>>"<<endl; } printf("%.4lf\n",cnt*1.0/q); } return 0;}
0 0
- hdu4126(最小生成树最佳替换边)
- hdu4756(最小生成树最佳替换边)
- HDU4126 最小生成树+树形dp
- hdu4126 Genghis Khan the Conqueror 树形dp+最小生成树
- HDU 4756:Install Air Conditioning (最小生成树最佳替换边,最小生成树+树形dp)
- hdu4126 Genghis Khan the Conqueror--最小生成树 & 树形DP(待解决)
- CCF201412-4 最佳灌溉(最小代价生成树)
- LA3887 最小生成树 枚举最小边
- 【最小生成树】CF160D最小生成树中的边
- 删边最小生成树
- 【POJ1679】【次小生成树】【替换边】
- 最小比例 最小生成树
- 最小生成树&&次最小生成树
- 最小生成生成树计数
- 最小生成树的最大边poj2395
- poj2395(最小生成树最大边)
- 树+最小生成树
- 最小生成树
- CSS Secret——Shapes
- Codeforences #297 div2 (A,B,C,D,E)
- 负数的二进制表示
- Android project的结构
- 第二章:probability distribution exercise45-52
- hdu4126(最小生成树最佳替换边)
- 前端面试
- 用户登录界面
- Web前端资源汇总
- leetcode 344 Reverse String
- SurfaceView开发示波器<略>
- android 蓝牙搜索功能实现
- 深入学习consul
- 设计模式之观察者模式