• HDU 3605 Escape 最大流


    题意:

    如果这是2012年世界末日怎么办?我不知道该怎么做。但是现在科学家们已经发现,有些星球上的人可以生存,但有些人却不适合居住。现在科学家们需要你的帮助,就是确定所有人都能在这些行星上生活。输入多组测试数据,每组数据的开头是n (1 <= n <= 100000), m (1 <= m <= 10) n表示地球上有n个人,m代表m星球,星球和人的标签都是从0开始的。这里有n行,每一行代表一个合适的居住条件的人,每一行有m个数字,第i个数字是1,表示一个人适合居住在第i个星球上,或者是0表示这个人不适合居住在第i个星球上。最后一行有m个数字,第i个数字ai表示第i个星球最能容纳ai人。0 <= ai <= 100000输出确定是否所有人都能达到这些标准如果可以输出YES,则输出NO。

    代码:

      1 //这道题一看见是一个最大流模板,但是这道题就是为了卡时间。。。
      2 //因为题目上面n特别大,这个时候因为m只有10,此时最大也就只有2^10个选择,所以有好多人的选择是一样的
      3 //那么我们要按照他们的选择来建图,这样的话边的数量就会大大减少
      4 #include<stdio.h>
      5 #include<string.h>
      6 #include<iostream>
      7 #include<algorithm>
      8 #include<queue>
      9 #include<math.h>
     10 #include<stdlib.h>
     11 #include<vector>
     12 using namespace std;
     13 const int maxn=200005;
     14 const int INF=0x3f3f3f3f;
     15 int head[maxn],cnt,st,en,dis[maxn],cur[maxn],v[maxn];
     16 struct edge
     17 {
     18     int v,next,c,flow;
     19 } e[1000005];
     20 vector<int> state[maxn];
     21 void add_edge(int x,int y,int z)
     22 {
     23     e[cnt].v=y;
     24     e[cnt].c=z;
     25     e[cnt].flow=0;
     26     e[cnt].next=head[x];
     27     head[x]=cnt++;
     28 
     29     e[cnt].v=x;
     30     e[cnt].c=z;
     31     e[cnt].flow=0;
     32     e[cnt].next=head[y];
     33     head[y]=cnt++;
     34 }
     35 bool bfs()
     36 {
     37     memset(dis,0,sizeof(dis));
     38     dis[st]=1;
     39     queue<int>r;
     40     r.push(st);
     41     while(!r.empty())
     42     {
     43         int x=r.front();
     44         r.pop();
     45         for(int i=head[x]; i!=-1; i=e[i].next)
     46         {
     47             int v=e[i].v;
     48             if(!dis[v] && e[i].c>e[i].flow)
     49             {
     50                 dis[v]=dis[x]+1;
     51                 r.push(v);
     52             }
     53         }
     54     }
     55     return dis[en];
     56 }
     57 int dinic(int s,int limit)
     58 {
     59     if(s==en || !limit) return limit;
     60     int ans=0;
     61     for(int &i=cur[s]; i!=-1; i=e[i].next)
     62     {
     63         int v=e[i].v,feed;
     64         if(dis[v]!=dis[s]+1) continue;
     65         feed=dinic(v,min(limit,e[i].c-e[i].flow));
     66         if(feed)
     67         {
     68             e[i].flow+=feed;
     69             e[i^1].flow-=feed;
     70             limit-=feed;
     71             ans+=feed;
     72             if(limit==0) break;
     73         }
     74     }
     75     if(!ans) dis[s]=-1;
     76     return ans;
     77 }
     78 int main()
     79 {
     80     int n,m;
     81     char s[25][25];
     82     int w[25][25];
     83     while(~scanf("%d%d",&n,&m))
     84     {
     85         memset(head,-1,sizeof(head));
     86         cnt=0;
     87         int x;
     88         st=0;
     89         en=1024+2*m+1;
     90         memset(v,0,sizeof(v));
     91 //        for(int i=1;i<=n;++i)   //这种方法建图的时候它的终止点en要大于1024,这样的话跑的话太慢了
     92 //        {   //所以这个时候en的大小要改变成n+m+1,这个时候就要用到n了,正确建图方式见下面
     93 //            int y=1,sum=0;
     94 //            for(int j=1;j<=m;++j)
     95 //            {
     96 //                scanf("%d",&x);
     97 //                if(x)
     98 //                {
     99 //                    sum+=y;
    100 //                }
    101 //                y*=2;
    102 //            }
    103 //            v[sum]++;
    104 //        }
    105 //        if(v[0])
    106 //        {
    107 //            printf("NO
    ");
    108 //            continue;
    109 //        }
    110 //        for(int i=1;i<=1024;++i)
    111 //        {
    112 //            if(v[i])
    113 //            {
    114 //                add_edge(st,i,v[i]);
    115 //                add_edge(i,st,0);
    116 //            }
    117 //            for(int j=0;j<m;++j)
    118 //            {
    119 //                if((1<<j)&i)
    120 //                {
    121 //                    add_edge(i,1024+1+j,INF);
    122 //                    add_edge(1024+1+j,i,0);
    123 //                }
    124 //            }
    125 //        }
    126 //        for(int i=1;i<=m;++i)
    127 //        {
    128 //            scanf("%d",&x);
    129 //            add_edge(1024+i,en,x);
    130 //            add_edge(en,1024+i,0);
    131 //        }
    132         st=0,en=n+m+1;
    133         int s,i,j,num;                          //因此用状态压缩进行缩点
    134         for(i=0; i<=1024; i++)
    135             state[i].clear();
    136         for(i=1; i<=n; i++)
    137         {
    138             s=0;
    139             for(j=0; j<m; j++)
    140             {
    141                 scanf("%d",&num);
    142                 if(num==1)
    143                     s|=(1<<j);  //C语言中的 |= 意思为:按位或后赋值
    144             }
    145             state[s].push_back(i);
    146         }                                       //缩点
    147         int tmp,siz;
    148         for(i=0; i<(1<<m); i++)  //这点就比我原来的代码优化了
    149         {
    150             if(state[i].size()==0)
    151                 continue;
    152             tmp=state[i][0];
    153             siz=state[i].size();
    154             add_edge(st,tmp,siz);
    155             for(j=0; j<m; j++)                  //由原来容量为1改为缩点的个数
    156                 if(i&(1<<j))
    157                     add_edge(tmp,n+j+1,siz);
    158         }
    159         for(i=1; i<=m; i++)
    160         {
    161             scanf("%d",&num);
    162             add_edge(i+n,en,num);
    163         }
    164 
    165         int ans=0;
    166         while(bfs())
    167         {
    168             for(int i=0; i<=en; i++)
    169                 cur[i]=head[i];
    170             ans+=dinic(st,INF);
    171         }
    172         if(ans==n)
    173         {
    174             printf("YES
    ");
    175         }
    176         else printf("NO
    ");
    177     }
    178     return 0;
    179 }
  • 相关阅读:
    jQueryEasyUi行编辑打造增删改查
    css样式DEMO
    jqueryEasyui常用代码
    Jquery easyui tree 一些常见操作
    EasyUI项目中的自定义JS
    easyui里弹窗的两种表现形式
    EasyUI扩展方法
    JS-easyui 扩展easyui.datagrid,添加数据loading遮罩效果代码
    Being a Hero (hdu 3251 最小割 好题)
    AWS携手上海嘉定政府推出首个联合孵化器 为创业公司拓展AWS云服务可用资源
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11837776.html
Copyright © 2020-2023  润新知