hdu4126 MST修改边后的期望值 树形dp 好题

来源:互联网 发布:万能蓝牙驱动软件 编辑:程序博客网 时间:2024/06/08 04:48
#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>#include<cmath>#include<map>#include<queue>#define lson l,m,rt<<1#define rson m+1,r,rt<<1 | 1#define lowbit(x) x&(-x)template <class T>inline bool rd(T &ret){    char c;int sgn;    if(c=getchar(),c==EOF) return 0;    while(c!='-' && (c<'0' || c>'9')) c=getchar();    sgn=(c=='-')?-1:1;    ret=(c=='-')?0:(c-'0');    while(c=getchar(),c>='0' && c<='9') ret=ret*10+(c-'0');    ret*=sgn;    return 1;}template <class T>inline void pt(T x){        if(x<0){            putchar('-');            x=-x;        }        if(x>9) pt(x/10);        putchar(x%10+'0');}using namespace std;typedef long long ll;const int N=3005;long long inf=1e15;const int MOD=1e9+7;int T,n,m,k,x,y,z,l,tot,cnt;ll g[N][N],d[N],mst,cost[N][N];bool vis[N],choose[N][N];vector<int> G[N];int pre[N];ll dfs(int u,int fa,int src){/*返回src为根的树中,src到u子树的非树边的最短距离*/    ll siz=inf;    for(int i=0;i<G[u].size();i++){        int v=G[u][i];        if(v==fa) continue;        ll tmp=dfs(v,u,src);        siz=min(siz,tmp);        cost[u][v]=min(cost[u][v],tmp);    }    if(fa!=src)/*如果不是树边*/        siz=min(siz,g[u][src]);    return siz;}void MST(){    for(int i=0;i<n;i++)    for(int j=0;j<n;j++)        cost[i][j]=g[i][j]=inf,choose[i][j]=0;    while(m--){        int u,v;ll dis;rd(u);rd(v);rd(dis);        g[u][v]=g[v][u]=min(g[u][v],dis);    }    for(int i=0;i<n;i++){        d[i]=inf;        G[i].clear();        vis[i]=0;        pre[i]=-1;    }    d[0]=0;    mst=0;    for(int i=0;i<n;i++){        int pos=-1;        for(int j=0;j<n;j++)            if(!vis[j] && (pos==-1 || d[pos]>d[j]))                pos=j;        if(pre[pos]!=-1){            G[pos].push_back(pre[pos]);            G[pre[pos]].push_back(pos);            choose[pos][pre[pos]]=choose[pre[pos]][pos]=1;        }        for(int j=0;j<n;j++)            if(d[j]>g[j][pos]){                d[j]=g[j][pos];                pre[j]=pos;            }        vis[pos]=1;        mst+=d[pos];    }}int main(){#ifndef  ONLINE_JUDGE freopen("aaa","r",stdin);#endif   int q,u,v;ll dis;   while(~scanf("%d%d",&n,&m),m+n){          MST();          for(int i=0;i<n;i++) dfs(i,-1,i);          rd(q);          ll ans=0;          for(int i=1;i<=q;i++){            rd(u);rd(v);rd(dis);            if(choose[u][v]==false) ans+=mst;/*修改边不在最小生成树上*/            else ans+=mst-g[u][v]+min(cost[u][v],dis);/*修改边在最小生成树上*/          }          printf("%.4f\n",(double)ans/(double)q);   }    return 0;}

0 0
原创粉丝点击