zoukankan      html  css  js  c++  java
  • [HihoCoder1393]网络流三·二分图多重匹配

    题目大意:

    班级有$N$名学生,运动会有$M$项不同的比赛,第$i$项比赛每个班需要派出$m_i$名选手参加,编号为i的学生最多同时参加给定的$b_i$项比赛中的任意$a_i$项比赛。
    根据统计的结果,想知道能否有一个合适的安排,同时满足这些条件。

    思路:

    最大流求二分图多重匹配。
    建立超级源点$S$、超级汇点$T$。
    对于每一个学生$s_i$,连一条从$S$到$s_i$的容量为$a_i$的边。
    对于每一项比赛$c_i$,连一条从$c_i$到$T$的容量为$m_i$的边。
    对于每一个学生$s_i$和其所擅长的所有比赛$c_j$,连一条从$s_i$到$c_j$的容量为1的边。
    计算最大流$F$,当$F=Σm_i$时,条件满足。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<vector>
     4 #include<queue>
     5 #include<cstring>
     6 inline int getint() {
     7     char ch;
     8     while(!isdigit(ch=getchar()));
     9     int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return x;
    12 }
    13 struct Edge {
    14     int from,to,remain;
    15 };
    16 const int E=10200,V=202,inf=0x7fffffff;
    17 Edge e[E<<1];
    18 int sz;
    19 std::vector<int> g[V];
    20 inline void add_edge(const int u,const int v,const int w) {
    21     e[sz]=(Edge){u,v,w};
    22     g[u].push_back(sz);
    23     sz++;
    24 }
    25 int s,t;
    26 void reset() {
    27     sz=0;
    28     for(int i=0;i<V;i++) g[i].clear();
    29 }
    30 int a[V],p[V];
    31 inline int Augment() {
    32     std::queue<int> q;
    33     q.push(s);
    34     memset(a,0,sizeof a);
    35     a[s]=inf;
    36     while(!q.empty()&&!a[t]) {
    37         int x=q.front();
    38         q.pop();
    39         for(unsigned i=0;i<g[x].size();i++) {
    40             Edge &y=e[g[x][i]];
    41             if(!a[y.to]&&y.remain) {
    42                 p[y.to]=g[x][i];
    43                 a[y.to]=std::min(a[x],y.remain);
    44                 q.push(y.to);
    45             }
    46         }
    47     }
    48     return a[t];
    49 }
    50 inline int EdmondsKarp() {
    51     int maxflow=0;
    52     while(int flow=Augment()) {
    53         for(int i=t;i!=s;i=e[p[i]].from) {
    54             e[p[i]].remain-=flow;
    55             e[p[i]^1].remain+=flow;
    56         }
    57         maxflow+=flow;
    58     }
    59     return maxflow;
    60 }
    61 int main() {
    62     for(int T=getint();T;T--) {
    63         reset();
    64         int n=getint(),m=getint();
    65         s=0,t=n+m+1;
    66         int sum=0;
    67         for(int i=1;i<=m;i++) {
    68             int w=getint();
    69             sum+=w;
    70             add_edge(n+i,t,w);
    71             add_edge(t,n+i,0);
    72         }
    73         for(int i=1;i<=n;i++) {
    74             int a=getint(),b=getint();
    75             add_edge(s,i,a);
    76             add_edge(i,s,0);
    77             while(b--) {
    78                 int v=getint();
    79                 add_edge(i,n+v,1);
    80                 add_edge(n+v,i,0);
    81             }
    82         }
    83         puts(EdmondsKarp()==sum?"Yes":"No");
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    Node.js基础学习一之Get请求
    Node.js学习准备篇
    如何在eclipse添加SVN菜单
    Java泛型的好处
    mybatis多数据源配置
    Python map() 函数
    python split()使用方法
    pythom os 模块
    深浅copy
    小数据池
  • 原文地址:https://www.cnblogs.com/skylee03/p/7251201.html
Copyright © 2011-2022 走看看