zoukankan      html  css  js  c++  java
  • uva 11865 stream my contest 最小树形图 朱刘算法

    G

    Stream My Contest

    Input: Standard Input

    Output: Standard Output

     

    During 2009 and 2010 ICPC world finals, the contest was webcasted via world wide web. Seeing this, some contest organizers from Ajobdesh decided that, they will provide a live stream of their contests to every university in Ajobdesh. The organizers have decided that, they will provide best possible service to them. But there are two problems:

     

    1. There is no existing network between universities. So, they need to build a new network. However, the maximum amount they can spend on building the network is C.

    2. Each link in the network has a bandwidth. If, the stream’s bandwidth exceeds any of the link’s available bandwidth, the viewers, connected through that link can’t view the stream.

     

    Due to the protocols used for streaming, a viewer can receive stream from exactly one other user (or the server, where the contest is organized). That is, if you have two 128kbps links, you won’t get 256kbps bandwidth, although, if you have a stream of 128kbps, you can stream to any number of users at that bandwidth.

     

    Given C, you have to maximize the minimum bandwidth to any user.

    Input

    First line of input contains T(≤50), the number of test cases. This is followed by T test cases.

     

    Each test case starts with an integer N,M,C(1≤N≤60,1≤M≤104,1≤C≤109), the number of universities and the number of possible links, and the budget for setting up the network. Each university is identified by an integer between 0 and N-1, where 0 is the server.

     

    Next M lines each contain 4 integers, u,v,b,c(0≤u, v<N, 1≤b, c≤106, u!=v), describing a possible link from university u to university v, that has the bandwidth of b kbps and of cost c. All links are unidirectional.

     

    There is a blank line before each test case.

    Output

    For each test case, output the maximum bandwidth to stream. If it’s not possible, output “streaming not possible.”.

    Sample Input                               Output for Sample Input

    3

     

    3 4 300

    0 1 128 100

    1 2 256 200

    2 1 256 200

    0 2 512 300

     

    3 4 500

    0 1 128 100

    1 2 256 200

    2 1 256 200

    0 2 512 300

     

    3 4 100

    0 1 128 100

    1 2 256 200

    2 1 256 200

    0 2 512 300

    128 kbps

    256 kbps

    streaming not possible.

     

     


    Problemsetter: Manzurur Rahman Khan, Special Thanks: Jane Alam & Derek Kisman

    第一次用(学)最小树形图的朱刘算法,看了众神题解后,这里的链接不错:http://www.cnblogs.com/nanke/archive/2012/04/11/2441725.html

    照书上代码敲了一遍,大概懂了,记下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<queue>
    #include<string>
    #include<cmath>
    #include<fstream>
    #include<iomanip>
    #include<climits>
    #include<cfloat>
    
    using namespace std;
    
    #define MAX_INT 0x7fffffff
    #define MAX_LL 0x7fffffffffffffff
    #define ULL unsigned long long
    #define LL long long
    #define MAX(x,y) ((x) > (y) ? (x) : (y))
    #define MIN(x,y) ((x) < (y) ? (x) : (y))
    
    #define MAXN 66
    #define MAXM 11111
    #define INF 1111111111
    struct node{
        int x,y,b,c;
        bool operator < (const node &rhs)const{
            return b>rhs.b;
        }
    }e[MAXM];
    int w[MAXN][MAXN];
    int n,m,c,cst;
    bool vis[MAXN],removed[MAXN];
    int pre[MAXN],cid[MAXN];
    int maxid,inv[MAXN];
    
    int dfs(int s){         //返回从s可达的点数
        int ans=1;
        vis[s]=true;
        for(int i=0; i<n; i++) if(!vis[i] && w[s][i]<INF)
            ans+=dfs(i);
        return ans;
    }
    
    void update(int s){     //求最小弧集
        inv[s]=INF;
        for(int i=0; i<n; i++) if(!removed[i] && w[i][s]<inv[s])
            inv[s]=w[i][s],pre[s]=i;
    }
                            //标记一个环
    bool cycle(int x){
        maxid++;
        int u=x;
        while(maxid!=cid[u]) cid[u]=maxid,u=pre[u];
        return u==x;
    }
    
    bool solve(int s){
        memset(vis, 0, sizeof(vis));
        if(dfs(s)<n) return false;      //判断图是否连通
        memset(cid, 0, sizeof(cid));
        memset(removed, 0, sizeof(removed));
        for(int i=0; i<n; i++) update(i);
        cst=maxid=0;
        pre[s]=s;   inv[s]=0;
        while(1){                   //当有圈,缩圈为点
            bool havecycle=false;
            for(int i=0; i<n; i++) if(!removed[i] && s!=i && cycle(i)){
                havecycle=true;
                int u=i;
                do{
                    if(u!=i) removed[u]=true;   //删除圈上的点,即圈当前圈为点i
                    cst+=inv[u];
                    for(int v=0; v<n; v++) if(cid[v]!=cid[i] && !removed[v]){
                        if(w[v][u]<INF) w[v][i]=MIN(w[v][i],w[v][u]-inv[u]);    //派生v指向u的弧指向i,且更新权值
                        w[i][v]=MIN(w[i][v],w[u][v]);       //指向圈外的弧
                        if(pre[v]==u) pre[v]=i;             //改变指向圈的弧方向
                    }
                    u=pre[u];                               //更新圈上下一点
                }while(u!=i);
                update(i);                              //缩圈完毕,继续求最小弧集
                break;
            }
            if(!havecycle) break;
        }
        for(int i=0; i<n; i++) if(!removed[i])
            cst+=inv[i];
        return true;
    }
    
    inline void add(node &t){
        w[t.x][t.y]=MIN(w[t.x][t.y],t.c);
    }
    
    bool ok(int cnt){
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                w[i][j]=INF;
        for(int i=0; i<=cnt; i++)
            add(e[i]);
        return solve(0) && cst<=c;
    }
    
    int main(){
         freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        int cas;
        scanf(" %d",&cas);
        while(cas--){
            scanf(" %d %d %d",&n,&m,&c);
            int i,j,x,y,b,c;
            for(i=0; i<m; i++){
                scanf(" %d %d %d %d",&x,&y,&b,&c);
                e[i]=(node){x,y,b,c};
            }
            sort(e, e+m);
            int ans=-1,l=0,r=m-1;
            while(l<=r){            //枚举前mid(inclusive)大的带宽link,
                int mid = (l+r)>>1;
                if(ok(mid)) {
                    ans=e[mid].b;     r=mid-1;
                }
                else l=mid+1;
            }
            if(ans<0) printf("streaming not possible.
    ");
            else printf("%d kbps
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    HDU1166:敌兵布阵(树状数组)
    elasticsearch 7.4.0依赖
    IntelliJ IDEA手工安装插件方法
    Guava入门
    Maven添加Oracle驱动及依赖
    springboot整合netty(二)
    MyBatis-Plus
    「Chris Richardson 微服务系列」服务发现的可行方案以及实践案例
    spring initializr
    String.Format( )用法
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3269286.html
Copyright © 2011-2022 走看看