uva11865 - 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 Ajobdeshdecided 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.

 

 

 

  N个位置编号0-N-1,服务器在位置0,要连接其它位置,给出连接线路的带宽和花费,最后的带宽是所有线路里带宽最小的那个,求在花费C以内的最大带宽。

  二分最小带宽,把大于等于这个带宽的边建成图,边权是花费,求最小树形图,如果求出的花费不大于C,说明这个带宽是可以的,否则是不行的。二分到最后就是答案。

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<queue>
#include<map>
using namespace std;

typedef pair<int,int> pii;

const int MAXN=65;
const int MAXM=40010;
const int MAXC=110;
const int MAXNODE=100010;
const int LOGMAXN=50;
const int INF=0x3f3f3f3f;

int T,N,M,C;
int iw[MAXN],cir[MAXN],vis[MAXN],pre[MAXN];
int ans;

struct Edge{
    int u,v,w,band;
    bool operator < (const Edge& rhs) const{
        return band<rhs.band;
    }
}e[MAXM],tmp[MAXM];

bool MDST(int s,int n,int m,Edge* e){
    ans=0;
    while(1){
        for(int i=0;i<n;i++) iw[i]=INF;
        for(int i=0;i<m;i++){
            int u=e[i].u,v=e[i].v;
            if(u!=v&&e[i].w<iw[v]){
                iw[v]=e[i].w;
                pre[v]=u;
            }
        }
        for(int i=0;i<n;i++) if(i!=s&&iw[i]==INF){
            return false;
        }
        int cid=0;
        iw[s]=0;
        memset(vis,-1,sizeof(vis));
        memset(cir,-1,sizeof(cir));
        for(int i=0;i<n;i++){
            ans+=iw[i];
            if(ans>C) return false;
            int v=i;
            while(vis[v]!=i&&cir[v]==-1&&v!=s){
                vis[v]=i;
                v=pre[v];
            }
            if(vis[v]==i){
                for(int u=pre[v];u!=v;u=pre[u]) cir[u]=cid;
                cir[v]=cid++;
            }
        }
        if(!cid){
            if(ans<=C) return true;
            return false;
        }
        for(int i=0;i<n;i++) if(cir[i]==-1){
            cir[i]=cid++;
        }
        for(int i=0;i<m;i++){
            int u=e[i].u,v=e[i].v;
            e[i].u=cir[u];
            e[i].v=cir[v];
            if(e[i].u!=e[i].v) e[i].w-=iw[v];
        }
        n=cid;
        s=cir[s];
    }
}

int main(){
    freopen("in.txt","r",stdin);
    int cas=0;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&N,&M,&C);
        int u,v,w;
        for(int i=0;i<M;i++) scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].band,&e[i].w);
        sort(e,e+M);
        for(int i=0;i<M;i++) tmp[i]=e[i];
        if(!MDST(0,N,M,tmp)){
            printf("streaming not possible.\n");
            continue;
        }
        int L=0,R=M;
        while(L+1<R){
            int mid=L+(R-L)/2,m=0;
            for(int i=mid;i<M;i++) tmp[m++]=e[i];
            if(MDST(0,N,m,tmp)) L=mid;
            else R=mid;
        }
        printf("%d kbps\n",e[L].band);
    }
    return 0;
}


用户表: Users +-------------+---------+ | Column Name | Type | +-------------+---------+ | user_id | int | | user_name | varchar | +-------------+---------+ user_id 是该表的主键(具有唯一值的列)。 该表中的每行包括用户 ID 和用户名。 注册表: Register +-------------+---------+ | Column Name | Type | +-------------+---------+ | contest_id | int | | user_id | int | +-------------+---------+ (contest_id, user_id) 是该表的主键(具有唯一值的列的组合)。 该表中的每行包含用户的 ID 和他们注册的赛事。 编写解决方案统计出各赛事的用户注册百分率,保留两位小数。 返回的结果表按 percentage 的 降序 排序,若相同则按 contest_id 的 升序 排序。 返回结果如下示例所示。 示例 1: 输入: Users 表: +---------+-----------+ | user_id | user_name | +---------+-----------+ | 6 | Alice | | 2 | Bob | | 7 | Alex | +---------+-----------+ Register 表: +------------+---------+ | contest_id | user_id | +------------+---------+ | 215 | 6 | | 209 | 2 | | 208 | 2 | | 210 | 6 | | 208 | 6 | | 209 | 7 | | 209 | 6 | | 215 | 7 | | 208 | 7 | | 210 | 2 | | 207 | 2 | | 210 | 7 | +------------+---------+ 输出: +------------+------------+ | contest_id | percentage | +------------+------------+ | 208 | 100.0 | | 209 | 100.0 | | 210 | 100.0 | | 215 | 66.67 | | 207 | 33.33 | +------------+------------+ 解释: 所有用户都注册了 208、209 和 210 赛事,因此这些赛事的注册率为 100% ,我们按 contest_id 的降序排序加入结果表中。 Alice 和 Alex 注册了 215 赛事,注册率为 ((2/3) * 100) = 66.67% Bob 注册了 207 赛事,注册率为 ((1/3) * 100) = 33.33%
03-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值