zoukankan      html  css  js  c++  java
  • [hdu 3605]Escape

    这题的做法非常直观,却又非常不直观

    先容许我吐一下槽吧~作者你的英语是读到火星上去了喵?

    题目大体是说人类要移民,然后有 n 个人, m 个星球

    每个人都有 m 个 0 、 1 数码表示他能否移民到该星球,每个星球有个最大人口容量

    问是否有方案移民该 n 个人

    乍一看很水,但是看看 n 的数据范围真是太感动人心了,有种这尼玛更本不是网络流的感脚——

    但是 m 的范围只有 10 !直觉告诉我似乎可以动手脚的样子喵?

    状压!因为不需要输出方案,所以两个可移民方案相同的人完全可以视为同一人

    然后点就被压到了 1024 以内,妥妥地过掉了~

    我才不会说我连边连错害我调了半小时呢喵

      1 #include <cstdio>
      2 #include <cstring>
      3 #define min(x, y) ((x)<(y) ? (x):(y))
      4 const int inf=0x7FFFFFFF;
      5 const int sizeOfPoint=10050;
      6 const int sizeOfEdge=500050;
      7 
      8 int n, m, t;
      9 int S, T;
     10 int f[sizeOfPoint], a[sizeOfPoint];
     11 
     12 struct edge {int point, flow; edge * next, * pair;};
     13 edge memory[sizeOfEdge], * port=memory;
     14 edge * e[sizeOfPoint];
     15 inline void clear() {port=memory; memset(e, 0, sizeof e); t=0; memset(f, 0, sizeof f);}
     16 inline edge * newedge(int point, int flow, edge * next) {edge * ret=port++; ret->point=point; ret->flow=flow; ret->next=next; ret->pair=NULL; return ret;}
     17 inline void build(int u, int v, int f) {e[u]=newedge(v, f, e[u]); e[v]=newedge(u, 0, e[v]); e[u]->pair=e[v]; e[v]->pair=e[u];}
     18 int h[sizeOfPoint];
     19 inline bool bfs();
     20 inline int aug();
     21 inline int dinic();
     22 
     23 int main()
     24 {
     25     int x, state;
     26 
     27     while (scanf("%d %d", &n, &m)!=EOF)
     28     {
     29         clear();
     30         for (int i=1;i<=n;i++)
     31         {
     32             state=0;
     33             for (int j=0;j<m;j++)
     34             {
     35                 scanf("%d", &x);
     36                 state|=x<<j;
     37             }
     38             if (!f[state]++) a[++t]=state;
     39         }
     40         S=0; T=t+m+1;
     41         for (int i=1;i<=t;i++)
     42         {
     43             build(S, i, f[a[i]]);
     44             for (int j=0;j<m;j++) if ((a[i]>>j)&1)
     45                 build(i, t+j+1, f[a[i]]);
     46         }    
     47         for (int i=1;i<=m;i++)
     48         {
     49             scanf("%d", &x);
     50             build(t+i, T, x);
     51         }
     52 
     53         if (dinic()==n) printf("YES
    ");
     54         else printf("NO
    ");
     55     }
     56 
     57     return 0;
     58 }
     59 inline bool bfs()
     60 {
     61     static int q[sizeOfPoint];
     62     int l=0, r=0;
     63     memset(h, 0xFF, sizeof h); h[T]=0;
     64     for (q[r++]=T;l<r;l++)
     65     {
     66         int u=q[l];
     67         for (edge * i=e[u];i;i=i->next) if (i->pair->flow && h[i->point]==-1)
     68             h[q[r++]=i->point]=h[u]+1;
     69     }
     70     return h[S]>=0;
     71 }
     72 inline int aug()
     73 {
     74     static edge * t[sizeOfPoint], * path[sizeOfPoint];
     75     static int aug[sizeOfPoint];
     76     int flow=0;
     77 
     78     memcpy(t, e, sizeof e);
     79     memset(path, 0, sizeof path);
     80     memset(aug, 0, sizeof aug);
     81     aug[S]=inf;
     82     for (int u=S; ; )
     83     {
     84         if (u==T)
     85         {
     86             flow+=aug[T];
     87             for (edge * i=path[T];i;i=path[i->point])
     88             {
     89                 i->pair->flow-=aug[T], i->flow+=aug[T];
     90                 aug[i->point]-=aug[T];
     91                 if (!aug[i->point]) h[i->point]=-1;
     92             }
     93             u=S;
     94         }
     95 
     96         edge *& i=t[u];
     97         for ( ;i && (!i->flow || h[u]!=h[i->point]+1);i=i->next);
     98         if (i)
     99         {
    100             path[i->point]=i->pair; aug[i->point]=min(aug[u], i->flow);
    101             u=i->point; i=i->next;
    102         }
    103         else
    104         {
    105             if (u==S) break;
    106             u=path[u]->point;
    107         }
    108     }
    109 
    110     return flow;
    111 }
    112 inline int dinic()
    113 {
    114     int ret=0, flow;
    115     while (bfs())
    116         while (flow=aug())
    117             ret+=flow;
    118     return ret;
    119 }
    本傻调出翔系列
  • 相关阅读:
    ExtJS小技巧
    Oracle 表的行数、表占用空间大小,列的非空行数、列占用空间大小 查询
    NPM 私服
    IDEA 不编译java以外的文件
    SQL 引号中的问号在PrepareStatement 中不被看作是占位符
    Chrome 浏览器自动填表呈现淡黄色解决
    批量删除Maven 仓库未下载成功.lastupdate 的文件
    Oracle 11g 监听很慢,由于监听日志文件太大引起的问题(Windows 下)
    Hibernate 自动更新表出错 建表或添加列,提示标识符无效
    Hibernate 自动更新表出错 More than one table found in namespace
  • 原文地址:https://www.cnblogs.com/dyllalala/p/3960739.html
Copyright © 2011-2022 走看看