UVA 11865 Stream My Contest(最小树形图+二分)

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=60+5;
const int maxm=10000+5;
const int inf=100000000;
int in[maxn],pre[maxn],vis[maxn],color[maxn],s[maxm],e[maxm],dis[maxm],cost[maxm];
int n,m,c;
int temps[maxm],tempe[maxm],tempd[maxm],tempc[maxm];
bool MDST(int root,int mincost)
{
    int ans=0;
    while(true)
    {
        memset(in,0x7f,sizeof(in));
        memset(pre,-1,sizeof(pre));
        for(int i=1;i<=m;i++){
            if(cost[i]<in[e[i]]&&s[i]!=e[i]){
                in[e[i]]=cost[i];
                pre[e[i]]=s[i];
            }
        }
        for(int i=1;i<=n;i++) if(i!=root&&pre[i]==-1) return false;
        int cnt=0;in[root]=0;;
        memset(vis,-1,sizeof(vis));
        memset(color,-1,sizeof(color));
        for(int i=1;i<=n;i++){
            int u,v=i;ans+=in[i];
            while(v!=root&&vis[v]==-1) {vis[v]=i;v=pre[v];}
            if(v!=root&&vis[v]==i)
                for(color[v]=++cnt,u=pre[v];u!=v;u=pre[u]) color[u]=cnt;
        }
        if(cnt==0) break;
        for(int i=1;i<=n;i++) if(color[i]==-1) color[i]=++cnt;
        for(int i=1;i<=m;i++){
            int u=s[i],v=e[i];
            s[i]=color[u],e[i]=color[v];
            if(color[u]!=color[v]) cost[i]-=in[v];
        }
        n=cnt;root=color[root];
    }
    if(ans<=c) return true;
    else return false;
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int k=1;k<=t;k++)
    {
        int tempn,tempm;
        int l=inf,r=-inf;
        scanf("%d%d%d",&n,&m,&c);
        tempn=n;tempm=m;
        for(int i=1;i<=m;i++) {
            scanf("%d%d%d%d",&s[i],&e[i],&dis[i],&cost[i]);
            s[i]++;e[i]++;
            temps[i]=s[i];tempe[i]=e[i];tempd[i]=dis[i];tempc[i]=cost[i];
            l=min(l,dis[i]);r=max(r,dis[i]);
            if(s[i]==e[i]) cost[i]=inf;
        }
        while(l<r)
        {
            int mid=l+(r-l+1)/2;
            n=tempn;m=tempm;
            for(int i=1;i<=m;i++) {
                s[i]=temps[i];e[i]=tempe[i];dis[i]=tempd[i];cost[i]=tempc[i];
                if(dis[i]<mid) cost[i]=inf;
            }
            bool ok=MDST(1,mid);
            if(ok) l=mid;
            else r=mid-1;
        }
        n=tempn;m=tempm;
        for(int i=1;i<=m;i++) {s[i]=temps[i];e[i]=tempe[i];dis[i]=tempd[i];cost[i]=tempc[i];}
        if(MDST(1,l)) printf("%d kbps\n",l);
        else printf("streaming not possible.\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值