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 }
    本傻调出翔系列
  • 相关阅读:
    机器学习中的贝叶斯方法---当后验分布无法计算时如何求得预测模型?
    机器学习中的贝叶斯方法---先验概率、似然函数、后验概率的理解及如何使用贝叶斯进行模型预测(2)
    机器学习中的贝叶斯方法---先验概率、似然函数、后验概率的理解及如何使用贝叶斯进行模型预测(1)
    使用最大似然法来求解线性模型(4)-最大化似然函数背后的数学原理
    使用最大似然法来求解线性模型(3)-求解似然函数
    使用最大似然法来求解线性模型(2)-为什么是最大化似然函数?
    使用最大似然法来求解线性模型(1)
    关于CPU的User、Nice、System、Wait、Idle各个参数的解释
    Redhat Linux FTP配置
    基于at91rm9200的i2c分析(DS1307实时时钟芯片)
  • 原文地址:https://www.cnblogs.com/dyllalala/p/3960739.html
Copyright © 2011-2022 走看看