zoukankan      html  css  js  c++  java
  • hdu 4126 Genghis Khan the Conqueror hdu 4756 Install Air Conditioning 最小生成树

    这两题思路一样。先说下题意。

    第一道就是一张图,q个操作,每次将一个边x,y增大到z,求出此时的最小生成树的值w,输出这q个w的平均值。

    第二道是一张完全图,但是有一条未知边不能选,求最小生成树最大可能是多少。

    对于第一道题,先求出最小生成树,对于每个操作x,y,z,假设x,y不是树边,那么w不变,如果是树边,那么假设这条边连接了u,v两个点集,那么只要添上一条两个点集间所有边的最小的那条即可。但是复杂度为n3,所以为了降低复杂度,要预处理出这条最小边,用dp[ i ][ j ]表示i,j两集合间的最小非树边。则对于每个操作减去树边再加上min( z, dp[x][y] )就是新树的值。

    再说下dfs过程,dfs(cur, u, fa ) 返回当前以cur为根,cur到u这棵子树中所有点的最小距离,dfs是沿着生成树的边进行的。

    先贴第一题代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    #define maxn 3100
    #define maxm 3100*2
    #define inf 1000000000
    struct Edge
    {
        int u,v,next;
    }e[maxm];
    int pre[maxn],low[maxn],head[maxn],cnt,n,m;
    bool vis[maxn][maxn];
    int dp[maxn][maxn],map[maxn][maxn];
    long long sum;
    void add(int u,int v)
    {
        e[cnt].u=u;
        e[cnt].v=v;
        e[cnt].next=head[u];
        head[u]=cnt++;
        e[cnt].u=v;
        e[cnt].v=u;
        e[cnt].next=head[v];
        head[v]=cnt++;
    
    }
    void prim()
    {
        int i,j;
        for(i=0;i<n;i++) {pre[i]=0;low[i]=map[i][0];}
        low[0]=0;pre[0]=-1;
        int u,v;
        sum=0;
        for(j=1;j<n;j++)
        {
            int Min=inf;
            for(i=0;i<n;i++)
            {
                if(pre[i]!=-1&&low[i]<Min)
                {
                    v=i;
                    Min=low[i];
                }
            }
            sum+=Min;
            vis[ pre[v] ][v]=vis[v][ pre[v] ]=1;
            add(pre[v],v);
            pre[v]=-1;
            for(i=1;i<n;i++)
                if(pre[i]!=-1&&low[i]>map[v][i])
                {
                    low[i]=map[v][i];
                    pre[i]=v;
                }
        }
    }
    
    int dfs(int pos,int u,int fa)
    {
        int res=inf,i;
        for(i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].v;
            if(v==fa) continue;
            int tmp=dfs(pos,v,u);
            dp[u][v]=dp[v][u]=min(tmp,dp[u][v]);
            res=min(res,tmp);
        }
        if(fa!=pos) res=min(res,map[pos][u]);
        return res;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m),n+m)
        {
            int i,j,Q;
            int x,y,z;
            memset(vis,0,sizeof(vis));
            cnt=0;
            for(i=0;i<n;i++)
            {
                head[i]=-1;
                for(j=0;j<n;j++)
                {
                    map[i][j]=inf;
                    dp[i][j]=inf;
                }
            }
            for(i=0;i<m;i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                map[y][x]=map[x][y]=z;
            }
            prim();
            for(i=0;i<n;i++)
                dfs(i,i,-1);
            //printf("a%da ",sum);
            scanf("%d",&Q);
            int que=Q;
            long long tot=0;
            while(que--)
            {
                scanf("%d%d%d",&x,&y,&z);
                if(!vis[x][y]) tot+=sum;
                else tot+=sum-map[x][y]+min(z,dp[x][y]);
            }
            //printf("a%llda",tot);
            printf("%.4lf
    ",(1.0*tot)/(Q*1.0));
        }
        return 0;
    }
    View Code

    第二题思路一样。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define N 1010
    #define inf 100000000000
    using namespace std;
    
    int n,k;
    int x[N],y[N];
    double dis[N][N];
    double d[N];
    int vis[N];
    bool mp[N][N];
    double ans;
    struct Edge
    {
        int v,next;
    }edge[N*2];
    int head[N],cnt;
    double dp[N][N];
    void init()
    {
        memset(head,-1,sizeof(head));
        cnt=0;
    }
    void add(int u,int v)
    {
        edge[cnt].v=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
        edge[cnt].v=u;
        edge[cnt].next=head[v];
        head[v]=cnt++;
    }
    void prim()
    {
        int i,j;
        for(i=0;i<n;i++)
        {
            vis[i]=0;
            d[i]=dis[0][i];
        }
        vis[0]=-1;
        ans=0;
        memset(mp,0,sizeof(mp));
        for(i=1;i<n;i++)
        {
            double Min=inf;
            int node=-1;
            for(j=0;j<n;j++)
            {
                if(vis[j]!=-1&&d[j]<Min)
                {
                    node=j;
                    Min=d[j];
                }
            }
            ans+=Min;
            mp[node][vis[node]]=mp[vis[node]][node]=1;
            add(vis[node],node);
            vis[node]=-1;
            for(j=0;j<n;j++)
            {
                if(vis[j]!=-1&&d[j]>dis[node][j])
                {
                    vis[j]=node;
                    d[j]=dis[node][j];
                }
            }
        }
    }
    
    double dfs(int cur,int u,int fa)
    {
        double res=(double)inf;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa) continue;
            double tmp=dfs(cur,v,u);
            dp[u][v]=dp[v][u]=min(tmp,dp[u][v]);
            res=min(res,tmp);
        }
        if(fa!=cur)
            res=min(res,dis[cur][u]);
        return res;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&k);
            for(int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]);
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                {
                    double tmp=(double)(x[i]-x[j])*(double)(x[i]-x[j])+(double)(y[i]-y[j])*(double)(y[i]-y[j]);
                    dis[i][j]=dis[j][i]=sqrt(tmp);
                }
            init();
            prim();
            for(int i=0;i<n;i++)
                for(int j=i;j<n;j++)
                    dp[i][j]=dp[j][i]=(double)inf;
            for(int j=0;j<n;j++)
                dfs(j,j,-1);
                double ANS=ans;
                for(int i=1;i<n;i++)
                    for(int j=i+1;j<n;j++)
                        if(mp[i][j])
                            ANS=max(ANS,ans-dis[i][j]+dp[i][j]);
            printf("%.2lf
    ",ANS*k);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Linux查看密码
    zabbix 邮件报警配置
    Linux 修改zabbix server的web访问端口
    Zabbix 配置监控主机
    Linux 安装zabbix
    Json解析注解 ---@SerializedName
    IntelliJ IDEA 设置背景图片
    @Override is not allowed when implementing interface method
    nginx ------反向代理和负载均衡
    IntelliJ IDEA 性能优化
  • 原文地址:https://www.cnblogs.com/vermouth/p/3836099.html
Copyright © 2011-2022 走看看