zoukankan      html  css  js  c++  java
  • UVALive 6887 Book Club 最大流解最大匹配

    题目连接:

      https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4899

    题意:

      给你n,m,m对关系

      m次输入,a,b,表示a喜欢b的书

      问你在随意安排数的情况下,是否每个人都能得到自己想要的书

    题解:

      也就是最大匹配数量,可以用最大流求或者匈牙利 

     每本书只能用一次,建边S-a a'-T

      有关系 a - b' 

      建图,跑最大流

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include<iostream>
    #include <algorithm>
    using namespace std;
    namespace NetFlow
    {
        const int MAXN=100000,MAXM=1000000,inf=1e9;
        struct Edge
        {
            int v,c,f,nx;
            Edge() {}
            Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
        } E[MAXM];
        int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz;
        void init(int _n)
        {
            N=_n,sz=0; memset(G,-1,sizeof(G[0])*N);
        }
        void link(int u,int v,int c)
        {
            E[sz]=Edge(v,c,0,G[u]); G[u]=sz++;
            E[sz]=Edge(u,0,0,G[v]); G[v]=sz++;
        }
        int ISAP(int S,int T)
        {//S -> T
            int maxflow=0,aug=inf,flag=false,u,v;
            for (int i=0;i<N;++i)cur[i]=G[i],gap[i]=dis[i]=0;
            for (gap[S]=N,u=pre[S]=S;dis[S]<N;flag=false)
            {
                for (int &it=cur[u];~it;it=E[it].nx)
                {
                    if (E[it].c>E[it].f&&dis[u]==dis[v=E[it].v]+1)
                    {
                        if (aug>E[it].c-E[it].f) aug=E[it].c-E[it].f;
                        pre[v]=u,u=v; flag=true;
                        if (u==T)
                        {
                            for (maxflow+=aug;u!=S;)
                            {
                                E[cur[u=pre[u]]].f+=aug;
                                E[cur[u]^1].f-=aug;
                            }
                            aug=inf;
                        }
                        break;
                    }
                }
                if (flag) continue;
                int mx=N;
                for (int it=G[u];~it;it=E[it].nx)
                {
                    if (E[it].c>E[it].f&&dis[E[it].v]<mx)
                    {
                        mx=dis[E[it].v]; cur[u]=it;
                    }
                }
                if ((--gap[dis[u]])==0) break;
                ++gap[dis[u]=mx+1]; u=pre[u];
            }
            return maxflow;
        }
        bool bfs(int S,int T)
        {
            static int Q[MAXN]; memset(dis,-1,sizeof(dis[0])*N);
            dis[S]=0; Q[0]=S;
            for (int h=0,t=1,u,v,it;h<t;++h)
            {
                for (u=Q[h],it=G[u];~it;it=E[it].nx)
                {
                    if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
                    {
                        dis[v]=dis[u]+1; Q[t++]=v;
                    }
                }
            }
            return dis[T]!=-1;
        }
        int dfs(int u,int T,int low)
        {
            if (u==T) return low;
            int ret=0,tmp,v;
            for (int &it=cur[u];~it&&ret<low;it=E[it].nx)
            {
                if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
                {
                    if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
                    {
                        ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp;
                    }
                }
            }
            if (!ret) dis[u]=-1; return ret;
        }
        int dinic(int S,int T)
        {
            int maxflow=0,tmp;
            while (bfs(S,T))
            {
                memcpy(cur,G,sizeof(G[0])*N);
                while (tmp=dfs(S,T,inf)) maxflow+=tmp;
            }
            return maxflow;
        }
    }
    using namespace NetFlow;
    int  n,m;
    int main(){
      while(~scanf("%d%d", &n, &m)) {
        init(20050);
        int S = 2*n+2, T = 2*n+1;
        for(int i = 0; i < m; i++) {
          int r, c;
          scanf("%d%d", &r, &c);
          r++;c++;
          link(c,r+n,1);
        }
        for(int i=1;i<=n;i++) {
            link(S,i,1);
            link(i+n,T,1);
        }
        int ans = dinic(S,T);
        if(ans == n) puts("YES");
        else puts("NO");
      }
      return 0;
    }
  • 相关阅读:
    asp.net Forms验证跨域页面不能访问的问题
    JavaScript创建命名空间
    DataTable转换成JSON字符串的函数
    javascript 正确截取单字节和双字节混和字符串的方法
    异常详细信息: 不能通过已删除的行访问该行的信息
    HttpUtility.ParseQueryString直接从字符串URL中提取参数
    支持函数,变量的算术表达式计算(三、加入函数)
    mp3 分类管理工具
    我好累
    电饭煲是如何知道饭已熟了的
  • 原文地址:https://www.cnblogs.com/zxhl/p/5674447.html
Copyright © 2011-2022 走看看