zoukankan      html  css  js  c++  java
  • [ZJOI2009]假期的宿舍

    OJ题号:

    洛谷2055、BZOJ1433

    思路:

    将需要住宿的学生与超极源点$S$连一条边,将所有的床与超极汇点$T$连一条边。
    将每个人与可以睡的床连一条边。
    最大流跑二分图最大匹配即可。
    连边时注意细节。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<vector>
     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 const int inf=0x7fffffff;
    14 int s,t;
    15 struct Edge {
    16     int from,to;
    17     bool remain;
    18 };
    19 const int E=5200,V=202;
    20 Edge e[E];
    21 std::vector<int> g[V];
    22 int sz;
    23 inline void add_edge(const int u,const int v,const bool w) {
    24     e[sz]=(Edge){u,v,w};
    25     g[u].push_back(sz);
    26     sz++;
    27 }
    28 int p[V];
    29 bool a[V];
    30 inline bool Augment() {
    31     memset(a,0,sizeof a);
    32     a[s]=inf;
    33     std::queue<int> q;
    34     q.push(s);
    35     while(!q.empty()&&!a[t]) {
    36         int x=q.front();
    37         q.pop();
    38         for(unsigned i=0;i<g[x].size();i++) {
    39             Edge &y=e[g[x][i]];
    40             if(!a[y.to]&&y.remain) {
    41                 p[y.to]=g[x][i];
    42                 a[y.to]=a[x]&&y.remain;
    43                 q.push(y.to);
    44             }
    45         }
    46     }
    47     return a[t];
    48 }
    49 inline int EdmondsKarp() {
    50     int maxflow=0;
    51     while(Augment()) {
    52         for(int i=t;i!=s;i=e[p[i]].from) {
    53             e[p[i]].remain^=true;
    54             e[p[i]^1].remain^=true;
    55         }
    56         maxflow++;
    57     }
    58     return maxflow;
    59 }
    60 inline void reset() {
    61     sz=0;
    62     for(int i=0;i<V;i++) {
    63         g[i].clear();
    64     }
    65 }
    66 int main() {
    67     for(int T=getint();T;T--) {
    68         reset();
    69         int n=getint();
    70         s=0,t=n<<1|1;
    71         bool isStudent[n+1];
    72         for(int i=1;i<=n;i++) {
    73             if(isStudent[i]=(bool)getint()) {
    74                 add_edge(n+i,t,true);
    75                 add_edge(t,n+i,false);
    76             }
    77         }
    78         int cnt=0;
    79         for(int i=1;i<=n;i++) {
    80             if(!getint()||!isStudent[i]) {
    81                 add_edge(s,i,true);
    82                 add_edge(i,s,false);
    83                 cnt++;
    84             }
    85         }
    86         for(int i=1;i<=n;i++) {
    87             for(int j=1;j<=n;j++) {
    88                 if(getint()||(i==j)) {
    89                     add_edge(i,n+j,true);
    90                     add_edge(n+j,i,false);
    91                 }
    92             }
    93         }
    94         puts(EdmondsKarp()==cnt?"^_^":"T_T");
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    CF821E 【Okabe and El Psy Kongroo】
    BZOJ1231: [Usaco2008 Nov]mixup2 混乱的奶牛
    P1896 [SCOI2005]互不侵犯
    QBXT Day 2 记录
    CF467C George and Job
    【luogu P3373 线段树2】 模板
    【luogu P1306 斐波那契公约数】 题解
    【luogu T24743 [愚人节题目5]永世隔绝的理想乡】 题解
    【luogu P1903 [国家集训队]数颜色】 题解
    莫队算法~讲解
  • 原文地址:https://www.cnblogs.com/skylee03/p/7257312.html
Copyright © 2011-2022 走看看