UVA 11865 最小树形图+二分

18 篇文章 0 订阅

http://vjudge.net/contest/view.action?cid=49353#problem/A 

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

题目大意:你需要花费不超过cost元来搭建一个比赛网络。网络中有n太机器,编号0~n-1,其中机器0为服务器,其他机器为客户机。一共有m条可以使用的网线,其中第i条网线的发送端是机器ui,接收端是机器vi(有向),带宽是bi,费用是ci元,每台客户机应当恰好从一台机器接受数据,而服务器不从任何一台机器接受数据。你的任务是最大化网络中的最下宽带。

分析:如果已知最小宽带,则问题转化为:如果唧哝小于此宽带的网线,是否可以搭建成功网络?利用最小树形图,不难做出判断。只需求出从零出发的最小树形图,判断权值和是否超过cost即可。由于最小宽带越小越容易有解,所以只需要二分这个最小带宽。

#include <cstdio>
#include <iostream>
#include <math.h>
#include <cstring>
using namespace std;
//======================================================================
//最小树形图(有向图的最小生成树)朱刘算法模板
const int N=101,M=11000,inf=2147483647;
struct edge
{
    int u,v;
    int w,c;
}e[M*5];
int n,m,id[N],pre[N],v[N],cost;
int inw[N];
bool zhu_liu(int root,int mid,int n)
{
    int s,t,idx=n;
    long long ans=0;
    while (idx)
    {
        for (int i=0; i<n; ++i)
            inw[i]=inf,id[i]=-1,v[i]=-1;
        for (int i=0; i<m; ++i)
        {
            s=e[i].u;
            t=e[i].v;
            if (e[i].c>=inw[t] || s==t||e[i].w<mid)
                continue;
            pre[t]=s;
            inw[t]=e[i].c;
        }
        inw[root]=0;
        pre[root]=root;
        for (int i=0; i<n; ++i)
        {
            if (inw[i]==inf)
                return false;
            ans+=inw[i];
        }
        idx=0;
        for (int i=0; i<n; ++i)
            if (v[i]==-1)
            {
                t=i;
                while (v[t]==-1)
                   v[t]=i,t=pre[t];
                if (v[t]!=i || t==root)
                    continue;
                id[t]=idx;
                for(s=pre[t]; s!=t; s=pre[s])
                    id[s]=idx++;
            }
        if(idx==0)
            continue;
        for(int i=0; i<n; ++i)
            if (id[i]==-1) id[i]=idx++;
        for(int i=0; i<m; ++i)
        {
            e[i].c-=inw[e[i].v];
            e[i].u=id[e[i].u];
            e[i].v=id[e[i].v];
        }
        n=idx;
        root=id[root];
    }
    if(ans<=cost)
        return true;
    else
        return false;
}
//==============================================================
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int maxb=0,minb=inf;
        scanf("%d%d%d",&n,&m,&cost);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].w,&e[i].c);
            e[i+m].u=e[i].u,e[i+m].v=e[i].v,e[i+m].w=e[i].w,e[i+m].c=e[i].c;
            maxb=max(maxb,e[i].w);
            minb=min(minb,e[i].w);
        }
       if(zhu_liu(0,minb,n)==false)
            printf("streaming not possible.\n");
        else
        {
            int l=minb,r=maxb;
            int mid;
            while(l<r)
            {
                mid=l+(r-l+1)/2;
                for(int i=0;i<m;i++)
                    e[i]=e[i+m];
                if(zhu_liu(0,mid,n)==true)
                    l=mid;
                else
                    r=mid-1;
            }
            printf("%d kbps\n",r);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值