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;
}
时间: 2024-12-10 20:28:01

UVALive 6887 Book Club 最大流解最大匹配的相关文章

poj1637 Sightseeing tour,混合图的欧拉回路问题,最大流解

混合图的欧拉回路问题 题目地址 欧拉回路问题 1 定义 欧拉通路 (Euler tour)--通过图中每条边一次且仅一次,并且过每一顶点的通路. 欧拉回路 (Euler  circuit)--通过图中每条边一次且仅一次,并且过每一顶点的回路. 欧拉图--存在欧拉回路的图.  2 无向图是否具有欧拉通路或回路的判定  G有欧拉通路的充分必要条件为:G 连通,G中只有两个奇度顶点(它们分别是欧拉通路的两个端点). G有欧拉回路(G为欧拉图):G连通,G中均为偶度顶点.  3 有向图是否具有欧拉通路或

MpegTS流解复用程序实现(解复用得到PES和ES)

MpegTS基础看这几篇博文: MpegTS基础 MpegTS之TS,PES,ES结构分析 TS流复用和解复用是一个相逆的过程.TS解复用得到的是音视频的PES裸流.一般来讲,每个TS包的长度是188个字节,也有一种204个字节的,就是在每个包后面加上16个字节的RS冗余校验信息.在这里分析188个字节的情况,其余的都类似了. 从文件中循环读取188个字节的包,然后对包进行逐字节分析,分析流程如下: TS包的标志是首字节以0x47开头 如下图是一个ts包: 按位解析,得到pid,flag,错误标

UVALive - 2531 The K-League(最大流+枚举)

题目大意:有n支队伍进行比赛,每支队伍需要打的比赛次数相同,每场比赛恰好有一支队伍胜,一支队伍败,给出每支队伍目前胜的场数和败的场数,以及每两支队伍还剩下的比赛场数,确定所有可能得冠军的队伍 解题思路:枚举每支队伍,然后让该队伍在接下来的所有比赛中都获胜. 建图的话,就比较简单了,源点连向每场比赛,容量为比赛次数 每场比赛连向比赛队伍,容量为比赛次数 接着每支队伍连向汇点,容量为枚举队伍的总胜场-该队伍的胜场 如果满流,表示该队伍可以得到冠军 #include <cstdio> #includ

UVALive - 5095 Transportation(拆边+费用流)

题目大意:有n个点,m条边,每条边的容量为ci,费用为ai* x^2(x为流量,ai为所给系数) 现在问能否将k个单位的货物从点1运输到点n,且费用最小 解题思路:拆边,将每条边拆成ci条边,每条边的费用分别为ai * 1, ai * 3, ai * 5-容量都为1,在容量相同的情况下,会选择费用少的流,这样流过的边累加起来的费用刚好为 ai * 流量^2 #include <cstdio> #include <cstring> #include <algorithm>

UVALive 2523 Machine Schedule(二分图求最大匹配数)

题意:有两台机器,上面有多个工作区域,有多个任务,分别可以在两台机器的某一个区域上完成,两台机器一开始都在0区域上工作,每次更改区域,都会重新启动一次,让我们求出最小的重启次数. 思路:将两个区域连线,使用二分图,求出最大匹配数,容易想明白,正好就是最小重启的次数. 注意:0一开始就已经完成,不应该加入到匹配序列. 代码如下: #include<iostream> #include<algorithm> #include<queue> #include<cstdi

HDU5900 QSC and Master(区间DP + 最小费用最大流)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, Northeastern University is the same. Enter from the north gate of Northeastern University,You are facing the main building of Northeastern University.

HDU 2853 (KM最大匹配)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853 题目大意:二分图匹配费用流.①最大匹配②最小原配变动 解题思路: 如果去掉第二个要求,那么就是裸KM. 然而加上第二个要求,那么就需要一种新的建图方式. 建图 对于输入矩阵,每一条边,cost扩大K倍($K=n+1$) 对于原配,每一条边cost在扩大K倍基础上+1 KM 统计cost时,直接把cost整除K,然后累加. 并且Hash一下原配边的变动情况. 扩大K倍的作用 准确来说,K倍是为了

分析IPNC_RDK H264编码器输出原始码流信息

最近在研究FLV视频格式,发现要想把H264码流解出来,就需要AVCDecoderConfigurationRecord 的信息,具体AVCDecoderConfigurationRecord  如何解析,可以参考:h264中avc和flv数据的解析 为了保证播放器可以正常解析数据出来,我们在打包数据格式无论是FLV还是MP4都必须提供AVCDecoderConfigurationRecord (里面包含里SPS序列参数集.PPS图片参数集,profie_idc,level_idc等信息),详细

【BZOJ4842】[Neerc2016]Delight for a Cat 线性规划+费用流

[BZOJ4842][Neerc2016]Delight for a Cat Description ls是一个特别堕落的小朋友,对于n个连续的小时,他将要么睡觉要么打隔膜,一个小时内他不能既睡觉也打隔膜,因此一个小时内他只能选择睡觉或者打隔膜,当然他也必须选择睡觉或打隔膜,对于每一个小时,他选择睡觉或打隔膜的愉悦值是不同的,对于第i个小时,睡觉的愉悦值为si,打隔膜的愉悦值为ei,同时又有一个奥妙重重的规定:对于任意一段连续的k小时,ls必须至少有t1时间在睡觉,t2时间在打隔膜.那么ls想让