zoukankan      html  css  js  c++  java
  • hdu 4292 最大流 水题

    很裸的一道最大流

    格式懒得排了,注意把人拆成两份,一份连接食物,一份连接饮料

    4 3 3  //4个人,3种食物,3种饮料
    1 1 1  //食物每种分别为1
    1 1 1  //饮料每种数目分别为1
    YYN   //第一个人对第1,2,3种食物的态度为接受,接受和拒绝
    NYY
    YNY
    YNY
    YNY   //第一个人对第1,2,3种饮料的态度为接受,拒绝和接受
    YYN
    YYN
    NNY

    3
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 using namespace std;
      8 const int maxn=11005;
      9 const int MAXN = 10010;//点数的最大值
     10 const int MAXM = 400010;//边数的最大值
     11 const int INF = 0x3f3f3f3f;
     12 struct Edge
     13 {
     14 int to,next,cap,flow;
     15 }edge[MAXM];//注意是MAXM
     16 int tol;
     17 int head[MAXN];
     18 int gap[MAXN],dep[MAXN],cur[MAXN];
     19 void init()
     20 {
     21     tol = 0;
     22     memset(head,-1,sizeof(head));
     23 }
     24 void addedge(int u,int v,int w,int rw = 0)
     25 {
     26     edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;
     27     edge[tol].next = head[u]; head[u] = tol++;
     28     edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0;
     29     edge[tol].next = head[v]; head[v] = tol++;
     30 }
     31 int Q[MAXN];
     32 void BFS(int start,int end)
     33 {
     34     memset(dep,-1,sizeof(dep));
     35     memset(gap,0,sizeof(gap));
     36     gap[0] = 1;
     37     int front = 0, rear = 0;
     38     dep[end] = 0;
     39     Q[rear++] = end;
     40     while(front != rear)
     41     {
     42         int u = Q[front++];
     43         for(int i = head[u]; i != -1; i = edge[i].next)
     44         {
     45             int v = edge[i].to;
     46             if(dep[v] != -1)continue;
     47             Q[rear++] = v;
     48             dep[v] = dep[u] + 1;
     49             gap[dep[v]]++;
     50         }
     51     }
     52 }
     53 int S[MAXN];
     54 int sap(int start,int end,int N)
     55 {
     56 BFS(start,end);
     57 memcpy(cur,head,sizeof(head));
     58 int top = 0;
     59 int u = start;
     60 int ans = 0;
     61 while(dep[start] < N)
     62 {
     63 if(u == end)
     64 {
     65 int Min = INF;
     66 int inser;
     67 for(int i = 0;i < top;i++)
     68 if(Min > edge[S[i]].cap - edge[S[i]].flow)
     69 {
     70 Min = edge[S[i]].cap - edge[S[i]].flow;
     71 inser = i;
     72 }
     73 for(int i = 0;i < top;i++)
     74 {
     75 edge[S[i]].flow += Min;
     76 edge[S[i]^1].flow -= Min;
     77 }
     78 ans += Min;
     79 top = inser;
     80 u = edge[S[top]^1].to;
     81 continue;
     82 }
     83 bool flag = false;
     84 int v;
     85 for(int i = cur[u]; i != -1; i = edge[i].next)
     86 {
     87 v = edge[i].to;
     88 if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])
     89 {
     90 flag = true;
     91 cur[u] = i;
     92 break;
     93 }
     94 }
     95 if(flag)
     96 {
     97 S[top++] = cur[u];
     98 u = v;
     99 continue;
    100 }
    101 int Min = N;
    102 for(int i = head[u]; i != -1; i = edge[i].next)
    103 if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
    104 {
    105 Min = dep[edge[i].to];
    106 cur[u] = i;
    107 }
    108 gap[dep[u]]--;
    109 if(!gap[dep[u]])return ans;
    110 dep[u] = Min + 1;
    111 gap[dep[u]]++;
    112 if(u != start)u = edge[S[--top]^1].to;
    113 }
    114 return ans;
    115 }
    116 int g[2000][2000];
    117 int main()
    118 {
    119     int i,j,k;
    120     #ifndef ONLINE_JUDGE
    121     freopen("1.in","r",stdin);
    122     #endif
    123     int n,d,f;
    124     while(scanf("%d%d%d",&n,&f,&d)!=EOF)
    125     {
    126         init();
    127         memset(g,0,sizeof(g));
    128         int start=0;
    129         int end=f+d+2*n+1;
    130         for(i=1;i<=f;i++)
    131         {
    132             scanf("%d",&g[0][i]);
    133             addedge(0,i,g[0][i]);
    134         }
    135         for(i=f+2*n+1;i<=f+2*n+d;i++)
    136         {
    137             scanf("%d",&g[i][1]);
    138             addedge(i,end,g[i][1]);
    139         }
    140         for(i=1;i<=n;i++)
    141         {
    142             addedge(f+i*2-1,f+i*2,1);
    143         }
    144         char s[250];
    145         for(i=1;i<=n;i++)
    146         {
    147             scanf("%s",s);
    148             for(int j=0;j<f;j++)
    149             {
    150                 if(s[j]=='Y')
    151                 {
    152                     addedge(j+1,f+2*i-1,1);
    153                 }
    154             }
    155         }
    156         for(i=1;i<=n;i++)
    157         {
    158             scanf("%s",s);
    159             for(int j=0;j<d;j++)
    160             {
    161                 if(s[j]=='Y')
    162                 {
    163                   addedge(f+2*i,f+2*n+j+1,1);
    164                 }
    165             }
    166         }
    167         printf("%d
    ",sap(start,end,d+f+2*n+1));
    168     }
    169     return 0;
    170 }
  • 相关阅读:
    小米手机做USB电脑摄像头啦,亲测可用,附有详细教程!
    【DIY文章列表标签】dt_gry_list
    Oracle 10g 设置 PL/SQL 远程
    关于硬盘“4K扇区”对齐的查看与设置方法
    oracle数据误操作恢复【flashback闪回操作】
    CENTOS下安装LNMP环境随笔
    深喉咙使用心得(陆续更新ing....)
    CENTOS6.3环境下安装VSFTPD 便于开通FTP功能随笔
    MYSQL/SQL_SERVER/ORACLE三种数据库自动备份方法
    U盘安装 ubuntu 12.04随笔
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4356582.html
Copyright © 2011-2022 走看看