zoukankan      html  css  js  c++  java
  • 【HNOI2013】消毒

    题面

    https://www.luogu.org/problem/P3231

    题解

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define ri register int
    #define N 5050
    #define INF 1000000007
    using namespace std;
    
    inline int read() {
      int f=0,ret=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0'&& ch<='9') ret=ret*10+(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    
    int T,a,b,c,cc;
    int A,B,C;
    int x[N],y[N],z[N];
    int mi;
    
    int count(int x) {
      int ret=0;
      for (ri i=0;i<=20;i++) if (x&(1<<i)) ret++;
      return ret;
    }
    
    struct graph {
      vector<int> ed[N];
      vector<int> w,to;
      int cur[N];
      int d[N];
      int cnt;
      
      void add_edge(int a,int b,int c) {
        ed[a].push_back(++cnt); to.push_back(b); w.push_back(c);
        ed[b].push_back(++cnt); to.push_back(a); w.push_back(0);
      }
      
      bool bfs() {
        for (ri i=0;i<=B+C+1;i++) d[i]=INF;
        queue<int> q;
        d[0]=0;
        q.push(0);
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0;i<ed[x].size();i++) {
            int e=ed[x][i];
            if (w[e] && d[to[e]]>d[x]+1) {
              d[to[e]]=d[x]+1;
              q.push(to[e]);
            }
          }
        }
        return d[B+C+1]<=10000;
      }
      
      int dfs(int x,int limit) {
        if (x==B+C+1 || !limit) return limit;
        int tot=0;
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (d[to[e]]!=d[x]+1 || !w[e]) continue;
          int f=dfs(to[e],min(limit,w[e]));
          if (!f) continue;
          w[e]-=f; w[1^e]+=f; limit-=f; tot+=f;
          if (!limit) return tot;
        }
        return tot;
      }
      
      int dinic() {
        int ret=0;
        while (bfs()) {
          for (ri i=0;i<=B+C+1;i++) cur[i]=0;
          ret+=dfs(0,INF);
        }
        return ret;
      }
      
      int mf(int s) {
        w.clear(); to.clear();
        for (ri i=0;i<=B+C+1;i++) ed[i].clear();
        cnt=-1;
        for (ri i=1;i<=cc;i++) if (!(s&(1<<(x[i]-1)))) add_edge(y[i],z[i]+B,1);
        for (ri i=1;i<=B;i++) add_edge(0,i,1);
        for (ri i=B+1;i<=B+C;i++) add_edge(i,B+C+1,1);
        return dinic();
      }
    } g;
    
    using namespace std;
    
    int main() {
      T=read();
      while (T--) {
        a=read(); b=read(); c=read();
        mi=1;
        if (b<a && b<c) mi=2; else if (c<a && c<b) mi=3;
        cc=0;
        for (ri i=1;i<=a;i++) {
          for (ri j=1;j<=b;j++) {
            for (ri k=1;k<=c;k++) {
              int w=read();
              if (!w) continue;
              if (mi==2) {
                x[++cc]=j,y[cc]=i,z[cc]=k;
              }
              else if (mi==3) {
                x[++cc]=k,y[cc]=j,z[cc]=i;
              }
              else 
                x[++cc]=i,y[cc]=j,z[cc]=k;
            }
          }
        }
        A=a,B=b,C=c;
        if (mi==2) swap(A,B); else if (mi==3) swap(A,C);
        int ans=A+B+C;
        for (ri i=0;i<(1<<A);i++) {
          int t=count(i)+g.mf(i);
          if (t<ans) ans=t;
        }
        cout<<ans<<endl;
      }
    }
  • 相关阅读:
    蛇形填数
    A Famous Music Composer
    Java用筛子法求素数
    素数求和问题
    Java中数组的快排
    大数阶乘
    Binary String Matching
    括号配对问题
    Android Studio安装和使用
    Android Studio使用手册
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11278624.html
Copyright © 2011-2022 走看看