uva 11865 (二分+ 最小树形图)

思路: 二分 bit  跑最小树形图是否满足花费的情况。

代码 : 

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N =65;
const int M =2e4+5;
const ll inf =1e18+5;

ll in[N];
int vis[N],id[N],pre[N];

struct Edge
{
    int u,v,f;
    ll b;
    ll c;
}edge[M],edges[M];

// kuangbin 板子

ll zhuliu(int root,int n,int m)
{
    ll res=0,u,v;

    while(1)
    {

    for(int i=0;i<n;i++) in[i]=inf;
    for(int i=0;i<m;i++){
        if(edges[i].u!=edges[i].v&&edges[i].c<in[edges[i].v])
        {
            in[edges[i].v]=edges[i].c;
            pre[edges[i].v]=edges[i].u;
        }
    }

    for(int i=0;i<n;i++){
        if(root!=i&&in[i]==inf) return -1;
    }

    int cnt=0;
    memset(id,-1,sizeof(id));
    memset(vis,-1,sizeof(vis));
    in[root]=0;

    for(int i=0;i<n;i++)
    {
        res+=in[i];
        v=i;
        while(vis[v]!=i&&id[v]==-1&&v!=root)
        {
            vis[v]=i;
            v=pre[v];
        }
        if(v!=root&&id[v]==-1){
            for(u=pre[v];u!=v;u=pre[u]) id[u]=cnt;
            id[v]=cnt++;
        }
    }

    if(cnt==0) break;

    for(int i=0;i<n;i++){
        if(id[i]==-1) id[i]=cnt++;
    }

    for(int i=0;i<m;)
    {
        v=edges[i].v;
        edges[i].u=id[edges[i].u]; edges[i].v=id[edges[i].v];
        if(edges[i].u!=edges[i].v)
        {
            edges[i++].c-=in[v];
        }
        else swap(edges[i],edges[--m]);
    }
    n=cnt;
    root=id[root];
    }
    return res;
}


int n,m,C;
int B[M];

int jud(ll num)
{
    int tot=0;
    for(int i=0;i<m;i++)
    {
        if(edge[i].b>=num)edges[tot++]=edge[i];
    }

    ll ans=zhuliu(0,n,tot);
    //cout<<"ans "<<ans<<endl;
    if(ans==-1) return 0;
    if(ans>C) return 0;
    return 1;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d %d",&n,&m,&C);
        for(int i=0;i<m;i++){
            scanf("%d %d %lld %lld",&edge[i].u,&edge[i].v,&edge[i].b,&edge[i].c);
            B[i]=edge[i].b;
        }
        sort(B,B+m);
        int tot=unique(B,B+m)-B;

        int l,r,mid;
        l=0; r=tot-1;
        ll ans=-1;
        while(l<=r)
        {
            mid=(l+r)>>1;
            //cout<<"mid "<<mid<<endl;
            if(jud(B[mid])){
               ans=B[mid];
               l=mid+1;
            }
            else r=mid-1;
        }
        if(ans==-1)
        {
            printf("streaming not possible.\n");
        }
        else printf("%lld kbps\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/81082344
今日推荐