zoukankan      html  css  js  c++  java
  • UVA 1345 Jamie's Contact Groups

    题意:

      一些人,和他们可能加入的组号。问每个组,最小的最大人数是多少

    分析:

      二分的是最大流的容量。设置一个超级源点,连向所有的人,容量为1。设置一个超级汇点,使所有的组连向超级汇点,二分的就是这里的容量(0~n)。然后根据题目给出的人和组的关系连接人和组,容量为1。二分时,若当前状态求出的最大流等于人数,则下界等于mid,若不等于,则上界等于mid。二分出的容量,就是组中的最小的最大人数。

    输入:

    3 2

    John 0 1

    Rose 1

    Mary 1

    5 4

    ACM 1 2 3

    ICPC 0 1

    Asian 0 2 3

    Regional 1 2

    ShangHai 0 2

    0 0 

    输出:

    2

    2

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <sstream>
    using namespace std;
    const int maxn=3010;
    const int inf=1e9;
    int n,m;
    structEdge
    {
        int u,v;
        int flow,cap;
        Edge(int uu,int cc,int fl,int ca):u(uu),v(cc),flow(fl),cap(ca)
        {
    
        }
    };
    vector<Edge>edge;
    structISAP
    {
        vector<int>G[maxn];
        vector<Edge>edge;
        int s,t;
        int d[maxn];
        int cur[maxn];
        int p[maxn];
        int num[maxn];
        int flow;
        void init()
        {
            for(int i=0;i<=n+m+1;i++)
                G[i].clear();
            s=0;
            t=n+m+1;
        }
        bool bfs()
        {
            memset(d,-1,sizeof(d));
            queue<int>q;
            q.push(t);
            d[t]=0;
            while(!q.empty())
            {
                int u=q.front();
                q.pop();
                for(int i=0;i<G[u].size();i++)
                {
                    Edge& e=edge[G[u][i]];
                    if(e.cap==0&&d[e.v]==-1)
                    {
                        d[e.v]=d[u]+1;
    					q.push(e.v);
                    }
                }
            }
            return d[s]!=-1;
        }
        int Augment()
        {
            int x=t,a=inf;
            while(x!=s)
            {
                Edge& e=edge[p[x]];
                a=min(a,e.cap-e.flow);
                x=edge[p[x]].u;
            }
            x=t;
            while(x!=s)
            {
                edge[p[x]].flow+=a;
                edge[p[x]^1].flow-=a;
                x=edge[p[x]].u;
            }
            return a;
        }
        int maxflow(int s,int t)
        {
            this->s=s;
            this->t=t;
            flow=0;
            bfs();
            for(int i=0;i<=n+m+1;i++)
                num[d[i]]++;
            int x=s;
            memset(cur,0,sizeof(cur));
            while(d[s]<n+m+2)
            {
                if(x==t)
                {
                    flow+=Augment();
                    x=s;
                }
                bool ok=false;
                for(int i=cur[x];i<G[x].size();i++)
                {
                    Edge& e=edge[G[x][i]];
                    if(e.cap>e.flow&&d[x]==d[e.v]+1)
                    {
                        ok=true;
                        p[e.v]=G[x][i];
                        cur[x]=i;
                        x=e.v;
                        break;
                    }
                }
                if(!ok)
                {
                    int k=n+m+1;
                    for(int i=0;i<G[x].size();i++)
                    {
                        Edge& e=edge[G[x][i]];
                        if(e.cap>e.flow)
                            k=min(k,d[e.v]);
                    }
                    if(--num[d[x]]==0)
                        break;
                    num[d[x]=k+1]++;
                    cur[x]=0;
                    if(x!=s)
                        x=edge[p[x]].u;
                }
            }
            return flow;
        }
    }solver;
    char buffer[11000];
    void add(int s,int t,int cap)
    {
        edge.push_back(Edge(s,t,0,cap));
        edge.push_back(Edge(t,s,0,0));
        int x=edge.size();
        solver.G[s].push_back(x-2);
        solver.G[t].push_back(x-1);
    }
    void input()
    {
        solver.init();
        int x;
        edge.clear();
        char ch[100];
        for (int i = 1 ; i <= n ; ++i)
        {
    		add(0,i,1);
    		scanf("%*s");
    		gets(buffer);
    		char * p = strtok(buffer, " ");
    		while (p) {
    			sscanf(p,"%d",&x);
    			add(i,x+1+n,1);
    			p = strtok(NULL," ");
    		}
    	}
        int sz=edge.size();
        for(int i=n+1;i<=n+m;i++)
        {
            sz+=2;
            solver.G[i].push_back(sz-2);
            solver.G[n+m+1].push_back(sz-1);
        }
    }
    void build(int up)
    {
        solver.edge=edge;
        for(int i=n+1;i<=n+m;i++)
        {
            solver.edge.push_back(Edge(i,n+m+1,0,up));
    		solver.edge.push_back(Edge(n+m+1,i,0,0));
        }
    }
    void solve()
    {
        int left=1,right=n;
        int mid=(left+right)>>1;
        int ans=n;
        while(left<=right)
        {
            build(mid);
            if (solver.maxflow(0,n+m+1)==n)
            {
    			right = mid-1;
    			ans = min(ans,mid);
    		}
    		else
            {
    			left = mid+1;
    		}
    		mid = (left+right)>>1;
        }
        printf("%d
    ",ans);
    }
    int main()
    {
    	while(scanf("%d%d",&n,&m)==2,n+m)
    	{
    		input();
    		solve();
    	}
    }
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <sstream>
    using namespace std;
    const int maxn=3010;
    const int inf=1e9;
    int n,m;
    structEdge
    {
        int u,v;
        int flow,cap;
        Edge(int uu,int cc,int fl,int ca):u(uu),v(cc),flow(fl),cap(ca)
        {
    
        }
    };
    vector<Edge>edge;
    structISAP
    {
        vector<int>G[maxn];
        vector<Edge>edge;
        int s,t;
        int d[maxn];
        int cur[maxn];
        int p[maxn];
        int num[maxn];
        int flow;
        void init()
        {
            for(int i=0;i<=n+m+1;i++)
                G[i].clear();
            s=0;
            t=n+m+1;
        }
        bool bfs()
        {
            memset(d,-1,sizeof(d));
            queue<int>q;
            q.push(t);
            d[t]=0;
            while(!q.empty())
            {
                int u=q.front();
                q.pop();
                for(int i=0;i<G[u].size();i++)
                {
                    Edge& e=edge[G[u][i]];
                    if(e.cap==0&&d[e.v]==-1)
                    {
                        d[e.v]=d[u]+1;
    					q.push(e.v);
                    }
                }
            }
            return d[s]!=-1;
        }
        int Augment()
        {
            int x=t,a=inf;
            while(x!=s)
            {
                Edge& e=edge[p[x]];
                a=min(a,e.cap-e.flow);
                x=edge[p[x]].u;
            }
            x=t;
            while(x!=s)
            {
                edge[p[x]].flow+=a;
                edge[p[x]^1].flow-=a;
                x=edge[p[x]].u;
            }
            return a;
        }
        int maxflow(int s,int t)
        {
            this->s=s;
            this->t=t;
            flow=0;
            bfs();
            for(int i=0;i<=n+m+1;i++)
                num[d[i]]++;
            int x=s;
            memset(cur,0,sizeof(cur));
            while(d[s]<n+m+2)
            {
                if(x==t)
                {
                    flow+=Augment();
                    x=s;
                }
                bool ok=false;
                for(int i=cur[x];i<G[x].size();i++)
                {
                    Edge& e=edge[G[x][i]];
                    if(e.cap>e.flow&&d[x]==d[e.v]+1)
                    {
                        ok=true;
                        p[e.v]=G[x][i];
                        cur[x]=i;
                        x=e.v;
                        break;
                    }
                }
                if(!ok)
                {
                    int k=n+m+1;
                    for(int i=0;i<G[x].size();i++)
                    {
                        Edge& e=edge[G[x][i]];
                        if(e.cap>e.flow)
                            k=min(k,d[e.v]);
                    }
                    if(--num[d[x]]==0)
                        break;
                    num[d[x]=k+1]++;
                    cur[x]=0;
                    if(x!=s)
                        x=edge[p[x]].u;
                }
            }
            return flow;
        }
    }solver;
    char buffer[11000];
    void add(int s,int t,int cap)
    {
        edge.push_back(Edge(s,t,0,cap));
        edge.push_back(Edge(t,s,0,0));
        int x=edge.size();
        solver.G[s].push_back(x-2);
        solver.G[t].push_back(x-1);
    }
    void input()
    {
        solver.init();
        int x;
        edge.clear();
        char ch[100];
        for (int i = 1 ; i <= n ; ++i)
        {
    		add(0,i,1);
    		scanf("%*s");
    		gets(buffer);
    		char * p = strtok(buffer, " ");
    		while (p) {
    			sscanf(p,"%d",&x);
    			add(i,x+1+n,1);
    			p = strtok(NULL," ");
    		}
    	}
        int sz=edge.size();
        for(int i=n+1;i<=n+m;i++)
        {
            sz+=2;
            solver.G[i].push_back(sz-2);
            solver.G[n+m+1].push_back(sz-1);
        }
    }
    void build(int up)
    {
        solver.edge=edge;
        for(int i=n+1;i<=n+m;i++)
        {
            solver.edge.push_back(Edge(i,n+m+1,0,up));
    		solver.edge.push_back(Edge(n+m+1,i,0,0));
        }
    }
    void solve()
    {
        int left=1,right=n;
        int mid=(left+right)>>1;
        int ans=n;
        while(left<=right)
        {
            build(mid);
            if (solver.maxflow(0,n+m+1)==n)
            {
    			right = mid-1;
    			ans = min(ans,mid);
    		}
    		else
            {
    			left = mid+1;
    		}
    		mid = (left+right)>>1;
        }
        printf("%d
    ",ans);
    }
    int main()
    {
    	while(scanf("%d%d",&n,&m)==2,n+m)
    	{
    		input();
    		solve();
    	}
    }
  • 相关阅读:
    【Java】:Java当中为什么不能够直接用==比较String字符串
    Mybatis
    spring boot
    IDEA
    IDEA
    kafka集群partition分布原理分析(转发)
    kafka集群partition分布原理分析(转发)
    scons ------ 基本使用
    色彩管理中的Gamma值的理解
    SFUD ------ (Serial Flash Universal Driver) 串行 Flash 通用驱动库
  • 原文地址:https://www.cnblogs.com/137033036-wjl/p/5761678.html
Copyright © 2011-2022 走看看