zoukankan      html  css  js  c++  java
  • UVA-11865 Stream My Contest (朱-刘 算法+二分)

    题目大意:有一张n个顶点,m条边的有向图,根节点为0。每条边有两个权值,一个是费用c,一个是长度b。问在总费用不超过cost的情况下选出若干条边,使得n个点连通时的边的最短长度的最大值是多少。

    题目分析:如果已知这个最短距离的最大值d,则问题就变成了:用长度不小于d的边能否构成一个总权值不大于cost的最小树形图。因此,二分枚举d,用朱-刘 算法判断即可。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define LL long long
    # define CL(a,b) memset(a,b,sizeof(a))
    
    const int INF=1<<30;
    struct Edge
    {
        int fr,to,w,d;
    };
    Edge e1[10005],e[10005];
    int n,m,cost,vis[65],ID[65],pre[65],in[65];
    
    int judge(int root,int nv,int ne)
    {
        int res=0;
        while(1){
            REP(i,0,nv) in[i]=INF;
            REP(i,0,ne) if(e[i].fr!=e[i].to&&in[e[i].to]>e[i].w){
                in[e[i].to]=e[i].w;
                pre[e[i].to]=e[i].fr;
            }
            in[root]=0;
            REP(i,0,nv) if(in[i]==INF) return -1;
            int nodeCnt=0;
            CL(ID,-1);
            CL(vis,-1);
            REP(i,0,nv){
                res+=in[i];
                int v=i;
                while(vis[v]!=i&&ID[v]==-1&&v!=root){
                    vis[v]=i;
                    v=pre[v];
                }
                if(v!=root&&ID[v]==-1){
                    for(int u=pre[v];u!=v;u=pre[u])
                        ID[u]=nodeCnt;
                    ID[v]=nodeCnt++;
                }
            }
            if(nodeCnt==0) break;
            REP(i,0,nv) if(ID[i]==-1) ID[i]=nodeCnt++;
            REP(i,0,ne){
                int v=e[i].to;
                e[i].fr=ID[e[i].fr];
                e[i].to=ID[e[i].to];
                if(e[i].fr!=e[i].to)
                    e[i].w-=in[v];
            }
            nv=nodeCnt;
            root=ID[root];
        }
        return res;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&cost);
            int l=0,r=0;
            REP(i,0,m){
                scanf("%d%d%d%d",&e1[i].fr,&e1[i].to,&e1[i].d,&e1[i].w);
                r=max(r,e1[i].d);
            }
            int ans=-1;
            while(l<r){
                int mid=l+(r-l+1)/2,cnt=0;
                REP(i,0,m) if(e1[i].d>=mid) e[cnt++]=e1[i];
                int x=judge(0,n,cnt);
                if(x>0&&x<=cost){
                    ans=l=mid;
                }else
                    r=mid-1;
            }
            if(ans<0)
                printf("streaming not possible.
    ");
            else
                printf("%d kbps
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    计算机视觉、机器学习相关领域论文和源代码大集合【转载】
    一试真伪:可以在12306上选择上中下卧铺吗
    给企业研发人员列一张数学清单【转载】
    向“生物力学之父”冯元桢先生学习什么?【转载】
    热消融影像引导
    Computer assisted surgery
    ASM, AAM
    Linux 下编译安装MySQL
    Linux下搭建FTP服务器
    自己瞎捣腾的Win7下Linux安装之路-----理论篇
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4915804.html
Copyright © 2011-2022 走看看