• HDU 3605 Escape(状态压缩+最大流)


    http://acm.hdu.edu.cn/showproblem.php?pid=3605

    题意:

    有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所有人都能去这m个星球之中。

    思路:

    这道题建图是关键,因为n的数量很大,如果直接将源点和人相连,是会超时的,因为m≤10,所以每个人的选择可以用二进制来存储,这样最多也就1<<m-1种状态,相同的就可以放在一起处理了。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<queue>
      6 using namespace std;
      7 
      8 const int maxn=1500;
      9 const int INF=0x3f3f3f3f;
     10 
     11 struct Edge
     12 {
     13     int from,to,cap,flow;
     14     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
     15 };
     16 
     17 struct Dinic
     18 {
     19     int n,m,s,t;
     20     vector<Edge> edges;
     21     vector<int> G[maxn];
     22     bool vis[maxn];
     23     int cur[maxn];
     24     int d[maxn];
     25 
     26     void init(int n)
     27     {
     28         this->n=n;
     29         for(int i=0;i<n;++i) G[i].clear();
     30         edges.clear();
     31     }
     32 
     33     void AddEdge(int from,int to,int cap)
     34     {
     35         edges.push_back( Edge(from,to,cap,0) );
     36         edges.push_back( Edge(to,from,0,0) );
     37         m=edges.size();
     38         G[from].push_back(m-2);
     39         G[to].push_back(m-1);
     40     }
     41 
     42     bool BFS()
     43     {
     44         queue<int> Q;
     45         memset(vis,0,sizeof(vis));
     46         vis[s]=true;
     47         d[s]=0;
     48         Q.push(s);
     49         while(!Q.empty())
     50         {
     51             int x=Q.front(); Q.pop();
     52             for(int i=0;i<G[x].size();++i)
     53             {
     54                 Edge& e=edges[G[x][i]];
     55                 if(!vis[e.to] && e.cap>e.flow)
     56                 {
     57                     vis[e.to]=true;
     58                     d[e.to]=d[x]+1;
     59                     Q.push(e.to);
     60                 }
     61             }
     62         }
     63         return vis[t];
     64     }
     65 
     66     int DFS(int x,int a)
     67     {
     68         if(x==t || a==0) return a;
     69         int flow=0, f;
     70         for(int &i=cur[x];i<G[x].size();++i)
     71         {
     72             Edge &e=edges[G[x][i]];
     73             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
     74             {
     75                 e.flow +=f;
     76                 edges[G[x][i]^1].flow -=f;
     77                 flow +=f;
     78                 a -=f;
     79                 if(a==0) break;
     80             }
     81         }
     82         return flow;
     83     }
     84 
     85     int Maxflow(int s,int t)
     86     {
     87         this->s=s; this->t=t;
     88         int flow=0;
     89         while(BFS())
     90         {
     91             memset(cur,0,sizeof(cur));
     92             flow +=DFS(s,INF);
     93         }
     94         return flow;
     95     }
     96 }DC;
     97 
     98 int n,m;
     99 int num[maxn];
    100 int src,dst;
    101 
    102 int main()
    103 {
    104     while(~scanf("%d%d",&n,&m))
    105     {
    106         memset(num,0,sizeof(num));
    107         for(int i=1;i<=n;i++)
    108         {
    109             int count=0;
    110             for(int j=m-1;j>=0;--j)
    111             {
    112                 int p;
    113                 scanf("%d",&p);
    114                 if(p) count |= 1<<j;
    115             }
    116             ++num[count];
    117         }
    118 
    119         src=(1<<m)+m;
    120         dst=(1<<m)+1+m;
    121         DC.init((1<<m)+2+m);
    122         for(int i=0;i<(1<<m);++i)
    123         if(num[i])
    124         {
    125             DC.AddEdge(src,i,num[i]);
    126             for(int j=0;j<m;++j)if(i&(1<<j))
    127                 DC.AddEdge(i,(1<<m)+j,INF);
    128         }
    129         for(int i=0;i<m;++i)
    130         {
    131             int p;
    132             scanf("%d",&p);
    133             DC.AddEdge((1<<m)+i,dst,p);
    134         }
    135 
    136         printf("%s
    ",DC.Maxflow(src,dst)==n?"YES":"NO");
    137     }
    138     return 0;
    139 }
  • 相关阅读:
    Python3学习笔记27-ConfigParser模块
    Python3学习笔记26-unittest模块
    HTML学习笔记09-列表
    HTML学习笔记08-表格
    [hdu1402]A * B Problem Plus(FFT模板题)
    [bzoj2179]FFT快速傅立叶
    [bzoj3884]上帝与集合的正确用法
    [ural1132]Square Root(cipolla算法)
    MD5算法的c++实现
    DES算法的c++实现
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6690792.html
Copyright © 2020-2023  润新知