poj4006 增大边权求MST
来源:互联网 发布:ubuntu tty 编辑:程序博客网 时间:2024/05/01 03:14
增大边权,求MST,多组询问(只询问,不修改)
做法:1.先求出原图MST,对树中每条边<u,v>,预处理best[u][v]:删除边<u,v>后u所在连通块和v所在连通块通过非树边连接的最短边长
求best[u][v]前还要预处理dp[rt][u]:以rt为根的树,rt到以u为根的子树中所有点通过非树边连接的最短边长
dp[rt][u]和best[u][v]都要通过dfs求出,具体求法见代码
#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>#include<vector>#include<queue>#define ll long long#define sf scanf#define pf printf#define INF 1<<29#define mem(a,b) memset(a,b,sizeof(a))#define lowbit(x) x&(-x)#define maxn 3010const ll mol=1000000007;using namespace std;int n,m,q;ll mst,ma[maxn][maxn],dp[maxn][maxn],best[maxn][maxn],ans;bool vis[maxn][maxn];struct Node{ int from,to; ll w; bool operator<(const Node &rhs)const{ return w<rhs.w; }}node[maxn*maxn];struct Edge{//MST int to,next; ll w;}edge[maxn<<2];int head[maxn],tot,p[maxn];void add(int u,int v,ll w){ edge[tot].to=v,edge[tot].w=w,edge[tot].next=head[u],head[u]=tot++;}int Find(int x){ return p[x]==x?x:(p[x]=Find(p[x])); }void kruscal(){ for(int i=1;i<=n;i++) p[i]=i; sort(node+1,node+m+1); mem(head,-1),tot=0,mst=0,mem(vis,0); for(int i=1;i<=m;i++){ int x=Find(node[i].from),y=Find(node[i].to); if(x!=y){ p[x]=y; vis[node[i].from][node[i].to]=vis[node[i].to][node[i].from]=1; add(node[i].from,node[i].to,node[i].w); add(node[i].to,node[i].from,node[i].w); mst+=node[i].w; } }}void dfs1(int u,int fa,int rt){ if(rt!=fa) dp[rt][u]=min(dp[rt][u],ma[u][rt]); for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; ll w=edge[i].w; if(v!=fa){ dfs1(v,u,rt); dp[rt][u]=min(dp[rt][u],dp[rt][v]); } }}ll dfs2(int u,int fa,int rt){ ll ans=dp[u][rt]; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(v!=fa){ ans=min(ans,dfs2(v,u,rt)); } } return ans;}int main(){ //freopen("a.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF,(m&&n)){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ ma[i][j]=(i==j)?0:INF; dp[i][j]=best[i][j]=INF; } for(int i=1;i<=m;i++){ scanf("%d%d%lld",&node[i].from,&node[i].to,&node[i].w); node[i].from++,node[i].to++; ma[node[i].from][node[i].to]=ma[node[i].to][node[i].from]=node[i].w; } kruscal(); for(int i=1;i<=n;i++){ dfs1(i,-1,i);//求以i为根的树,i到达树中任意一点为根的子树非树边的最小值 } for(int u=1;u<=n;u++){ for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; best[u][v]=best[v][u]=dfs2(v,u,u); } } scanf("%d",&q); int qq=q; ans=0; while(qq--){ int a,b; ll c; scanf("%d%d%lld",&a,&b,&c); a++,b++; if(!vis[a][b]) ans+=mst; else{ if(best[a][b]>c) ans+=(mst+c-ma[a][b]); else ans+=(mst+best[a][b]-ma[a][b]); } } double answer=(double)ans/(double)q; printf("%.4f\n",answer); } return 0;}
0 0
- poj4006 增大边权求MST
- LA5713 减小边权求MST
- MST
- MST
- MST......
- mst
- MST
- MST
- MST
- 增大framebuffer
- 增大数据文件
- 增大redo
- 【MST】MST唯一性
- tomcat 增大jvm内存、增大连接数
- PVST+,MST
- POJ1251 MST
- hdu1102(MST)
- 初识MST
- hibernate双向一对多关联
- [汉诺塔][第二阶段-汉诺塔入门][HDOJ-2064]汉诺塔III
- configure: error: no acceptable m4 could be found in $PATH
- autoconf安装实现库文件的具体步骤
- Oracle 中如何判断一个字符串是否为数字
- poj4006 增大边权求MST
- 我的开源视音频项目汇总
- android中杀死进程的方法
- LeetCode--Search a 2D Matrix
- 用BCB做一个自己的Color Dector --- 实时显示鼠标所在位置的像素值
- 产品经理之复审原型
- gradle学习(19)-log系统
- 对pair的sort
- automake 安装及使用