dyllalala

导航

[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\n");
 54         else printf("NO\n");
 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 }
本傻调出翔系列

 

posted on 2014-09-07 20:27  dyllalala  阅读(149)  评论(0编辑  收藏  举报