• HDU 4292 Food (成都赛区网络赛第五题,拆点网络流)


     

    题意:跟POJ3281基本上一样的拆点网络流。

    建图:建一超级源点和一超级汇点,源点与食物相连,边权为其数量,汇点与饮料相连,边权也为其数量,把人分成两个点,之间的边权为1。每个人与之需要的食物和饮料相连,边权为1。

    代码(SAP模板):

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <queue>
      6 using namespace std;
      7 const int maxn=101050;
      8 const int maxm=3000000;
      9 const int oo=1<<30;
     10 int idx,N,F,D;
     11 int cur[maxn],pre[maxn];
     12 int dis[maxn],gap[maxn];
     13 int aug[maxn],head[maxn];
     14 struct Node
     15 {
     16     int u, v, w;
     17     int next;
     18 }edge[maxm];
     19 void addEdge(int u, int v, int w)
     20 {
     21     edge[idx].u=u;
     22     edge[idx].v=v;
     23     edge[idx].w=w;
     24     edge[idx].next=head[u];
     25     head[u]=idx++;
     26     edge[idx].u=v;
     27     edge[idx].v=u;
     28     edge[idx].w=0;
     29     edge[idx].next=head[v];
     30     head[v]=idx++;
     31 }
     32 int SAP(int s,int e,int n)
     33 {
     34     int max_flow=0,v,u=s;
     35     int id,mindis;
     36     aug[s]=oo;
     37     pre[s]=-1;
     38     memset(dis,0,sizeof(dis));
     39     memset(gap,0,sizeof(gap));
     40     gap[0] = n;
     41     for (int i=0;i<=n;i++)
     42     {
     43         cur[i]=head[i];
     44     }
     45     while(dis[s]<n)
     46     {
     47         bool flag=false;
     48         if(u==e)
     49         {
     50             max_flow+=aug[e];
     51             for (v=pre[e];v!=-1;v=pre[v])
     52             {
     53                 id = cur[v];
     54                 edge[id].w-=aug[e];
     55                 edge[id^1].w+=aug[e];
     56                 aug[v]-=aug[e];
     57                 if (edge[id].w==0)
     58                 u=v;
     59             }
     60         }
     61         for(id=cur[u];id!=-1;id=edge[id].next)
     62         {
     63             v=edge[id].v;
     64             if(edge[id].w>0&&dis[u]==dis[v]+1)
     65             {
     66                 flag=true;
     67                 pre[v]=u;
     68                 cur[u]=id;
     69                 aug[v]=min(aug[u], edge[id].w);
     70                 u=v;
     71                 break;
     72             }
     73         }
     74         if (flag==false)
     75         {
     76             if(--gap[dis[u]]==0)
     77             break;
     78             mindis=n;
     79             cur[u]=head[u];
     80             for(id=head[u];id!=-1;id=edge[id].next)
     81             {
     82                 v=edge[id].v;
     83                 if(edge[id].w>0&&dis[v]<mindis)
     84                 {
     85                     mindis=dis[v];
     86                     cur[u]=id;
     87                 }
     88             }
     89             dis[u]=mindis+1;
     90             gap[dis[u]]++;
     91             if(u!=s)
     92             u=pre[u];
     93         }
     94     }
     95     return max_flow;
     96 }
     97 int main()
     98 {
     99     while(~scanf("%d%d%d",&N,&F,&D))
    100     {
    101         int source=0,sink=N+N+F+D+10;
    102         memset(head,-1,sizeof(head));
    103         idx=0;
    104         int a,b,f,d;
    105         int food [10000];
    106         int drink[10000];
    107         char str[500][500];
    108         for(int i=1;i<=F;i++)
    109         {
    110             scanf("%d",&food[i]);
    111             addEdge(source,i,food[i]);
    112         }
    113         for(int i=1;i<=D;i++)
    114         {
    115             scanf("%d",&drink[i]);
    116             addEdge(i+F,sink,drink[i]);
    117         }
    118         for(int i=1;i<=N;i++)
    119         {
    120             addEdge(D+F+i,D+F+N+i,1);
    121         }
    122         for(int i=1;i<=N;i++)
    123         {
    124             scanf("%s",str[i]+1);
    125             for(int j=1;j<=F;j++)
    126             {
    127                 if(str[i][j]=='Y')
    128                 {
    129                     addEdge(j,F+D+i,1);
    130                 }
    131             }
    132         }
    133 
    134         for(int i=1;i<=N;i++)
    135         {
    136             scanf("%s",str[i]+1);
    137             for(int j=1;j<=D;j++)
    138             {
    139                 if(str[i][j]=='Y')
    140                 {
    141                     addEdge(F+D+N+i,F+j,1);
    142                 }
    143             }
    144         }
    145         int n=sink+1;
    146         printf("%d\n",SAP(source,sink,n));
    147     }
    148     return 0;
    149 }
  • 相关阅读:
    Java反射机制源码分析及知识点总结
    Dubbo admin 在Windows下的安装和服务发现
    Redis知识点总结
    Error:(xx) java: -source 1.5 中不支持
    Java中的线程间通信
    linux主机名显示bogon问题
    Linux(CentOS)上安装Apache Hadoop
    Java虚拟机(JVM)及其体系结构
    在微服务领域中处理分布式事务
    Redis持久化
  • 原文地址:https://www.cnblogs.com/pony1993/p/2703734.html
Copyright © 2020-2023  润新知