• UVA11865 Stream My Contest(最小树形图)


    刘汝佳新书--训练指南

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

    分析:最小树形图,然后二分答案最小带宽。

    // File Name: 11865.cpp
    // Author: zlbing
    // Created Time: 2013/2/17 22:36:04
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define MAXN 205
    struct Edge{
        int from,to,dist,band;
    }edges[MAXN*MAXN];
    int In[MAXN];
    int pre[MAXN],ID[MAXN],vis[MAXN];
    bool Directed_MST(int root,int n,int m,int C,int B)
    {
        long long ans=0;
        while(true)
        {
            //1、找最小入边
            for(int i=0;i<n;i++)In[i]=INF;
            for(int i=0;i<m;i++)
            {
                int u=edges[i].from;
                int v=edges[i].to;
                if(edges[i].dist<In[v]&&u!=v&&edges[i].band>=B)
                {
                    pre[v]=u;
                    In[v]=edges[i].dist;
                }
            }
            //2、判断是否有最小生成树
            for(int i=0;i<n;i++)
            {
                if(i==root)continue;
                if(In[i]==INF)return false;
            }
            //3、找环
            int cntnode=0;
            CL(ID,-1);
            CL(vis,-1);
            In[root]=0;
            for(int i=0;i<n;i++)
            {
                ans+=In[i];
                int v=i;
                while(vis[v]!=i&&ID[v]==-1&&v!=root)
                {
                    vis[v]=i;
                    v=pre[v];
                }
                if(v!=root&&ID[v]==-1)
                {
                    for(int u=pre[v];u!=v;u=pre[u])
                    {
                        ID[u]=cntnode;
                    }
                    ID[v]=cntnode++;
                }
            }
            if(cntnode==0)break;
            for(int i=0;i<n;i++)
                if(ID[i]==-1)
                    ID[i]=cntnode++;
            //4、缩点,重新标记
            for(int i=0;i<m;i++)
            {
                int v=edges[i].to;
                edges[i].from=ID[edges[i].from];
                edges[i].to=ID[edges[i].to];
                if(edges[i].from!=edges[i].to)
                {
                    edges[i].dist-=In[v];
                }
            }
            n=cntnode;
            root=ID[root];
        }
        if(ans<=C)
        return true;
        else return false;
    }
    int main(){
        int T;
        scanf("%d",&T);
        int N,M,C;
        while(T--)
        {
            scanf("%d%d%d",&N,&M,&C);
            int a,b,c,d;
            int maxn=0,minn=INF;
            for(int i=0;i<M;i++)
            {
                scanf("%d%d%d%d",&a,&b,&c,&d);
                edges[i].from=a;
                edges[i].to=b;
                edges[i].band=c;
                edges[i].dist=d;
                edges[i+M].from=a;
                edges[i+M].to=b;
                edges[i+M].band=c;
                edges[i+M].dist=d;
                maxn=max(maxn,c);
                minn=min(minn,c);
            }
            if(Directed_MST(0,N,M,C,minn)==false)
                printf("streaming not possible.\n");
            else{
                int L=minn,R=maxn;
                while(L<R)
                {
                    int mid=L+(R-L+1)/2;
                    for(int i=0;i<M;i++)
                    edges[i]=edges[i+M];
                    if(!Directed_MST(0,N,M,C,mid))
                        R=mid-1;
                    else L=mid;
                }
                printf("%d kbps\n",L);
            }
        }
        return 0;
    }
  • 相关阅读:
    内存管理简介之Buddy算法和slab分配
    进程通信方式介绍
    Linux内核网络栈实现分析(十一)驱动程序层(下)
    Linux内核网络协议栈深入分析(二)sk_buff的操作函数
    Linux内核网络协议栈深入分析(一)与sk_buff有关的几个重要的数据结构
    内核源码学习:伙伴算法
    寒假Day16Dinic模板更新+优化
    寒假Day20:数位dp
    寒假Day21:Catalan Square卡特兰数 JAVA写大数
    寒假Day17UVALive3231Fair Share(最大流+二分)
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2915073.html
Copyright © 2020-2023  润新知