题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4292

题意:水和饮料,建图跑最大流模板。

我用的是学长的模板,最然我还没有仔细理解,不过这都不重要直接贴就行了。

下面是AC代码,以后就当做最大流的模板来用了。

代码:

#include<cstdio>
#include<iostream>
using namespace std; const int oo=1e9;
const int mm=2e5+;
const int mn=1e5+; int node,src,dest,edge;
int ver[mm],flow[mm],Next[mm];
int head[mn],work[mn],dis[mn],q[mn]; int Min(int a,int b)
{
return a<b?a:b;
} void prepare(int _node,int _src,int _dest)
{
node=_node,src=_src,dest=_dest;
for(int i=; i<node; ++i)head[i]=-;
edge=;
} void Addedge(int u,int v,int c)
{
ver[edge]=v,flow[edge]=c,Next[edge]=head[u],head[u]=edge++;
ver[edge]=u,flow[edge]=,Next[edge]=head[v],head[v]=edge++;
} bool Dinic_bfs()
{
int i,u,v,l,r=;
for(i=; i<node; ++i)dis[i]=-;
dis[q[r++]=src]=;
for(l=; l<r; ++l)
for(i=head[u=q[l]]; i>=; i=Next[i])
if(flow[i]&&dis[v=ver[i]]<)
{
dis[q[r++]=v]=dis[u]+;
if(v==dest)return ;
}
return ;
} int Dinic_dfs(int u,int exp)
{
if(u==dest)return exp;
for(int &i=work[u],v,tmp; i>=; i=Next[i])
if(flow[i]&&dis[v=ver[i]]==dis[u]+&&(tmp=Dinic_dfs(v,Min(exp,flow[i])))>)
{
flow[i]-=tmp;
flow[i^]+=tmp;
return tmp;
}
return ;
} int Dinic_flow()
{
int i,ret=,delta;
while(Dinic_bfs())
{
for(i=; i<node; ++i) work[i]=head[i];
while(delta=Dinic_dfs(src,oo)) ret+=delta; }
return ret;
} int main()
{
char s[];
int n,f,d,t;
while(scanf("%d%d%d",&n,&f,&d)==)
{
prepare(n*+f+d+,,n*+f+d+);
for(int i=; i<=f; i++)
{
scanf("%d",&t);
Addedge(,i,t);///源点加边
}
for(int i=; i<=d; i++)
{
scanf("%d",&t);
Addedge(f+*n+i,f+*n+d+,t);///汇点加边
}
for(int i=; i<=n; i++)
Addedge(f+i,f+n+i,);///拆点
for(int i=; i<=n; i++)
{
scanf("%s",s+);
for(int j=; j<=f; j++)
if(s[j]=='Y')
Addedge(j,f+i,);///顾客与食物加边
}
for(int i=; i<=n; i++)
{
scanf("%s",s+);
for(int j=; j<=d; j++)
if(s[j]=='Y')
Addedge(f+n+i,f+*n+j,);///顾客与饮料加边
}
printf("%d\n",Dinic_flow());
}
return ;
}

学长模板的链接:http://m.blog.csdn.net/article/details?id=30030439

模板:

#include<cstdio>
#include<iostream>
using namespace std;
const int oo=1e9; const int mm=;
const int mn=;
int node,src,dest,edge;
int ver[mm],flow[mm],next[mm];
int head[mn],work[mn],dis[mn],q[mn]; void prepare(int _node,int _src,int _dest) ///node是结点总数
{
node=_node,src=_src,dest=_dest;
for(int i=; i<node; ++i)head[i]=-;
edge=;
} void addedge(int u,int v,int c)
{
ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++;
ver[edge]=u,flow[edge]=,next[edge]=head[v],head[v]=edge++;
} bool Dinic_bfs()
{
int i,u,v,l,r=;
for(i=; i<node; ++i)dis[i]=-;
dis[q[r++]=src]=;
for(l=; l<r; ++l)
for(i=head[u=q[l]]; i>=; i=next[i])
if(flow[i]&&dis[v=ver[i]]<)
{
dis[q[r++]=v]=dis[u]+;
if(v==dest)return ;
}
return ;
} int Dinic_dfs(int u,int exp)
{
if(u==dest)return exp;
for(int &i=work[u],v,tmp; i>=; i=next[i])
if(flow[i]&&dis[v=ver[i]]==dis[u]+&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>)
{
flow[i]-=tmp;
flow[i^]+=tmp;
return tmp;
}
return ;
}
int Dinic_flow()
{
int i,ret=,delta;
while(Dinic_bfs())
{
for(i=; i<node; ++i)work[i]=head[i];
while(delta=Dinic_dfs(src,oo))ret+=delta;
}
return ret;
}

SAP模板:

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std; const int MAXN=;//点数的最大值
const int MAXM=**;//边数的最大值
const int INF=0x3f3f3f3f; struct Edge
{
int to,next,cap,flow;
} edge[MAXM]; //注意是MAXM int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN]; void init()
{
tol=;
memset(head,-,sizeof(head));
}
//加边,单向图三个参数,双向图四个参数
void addedge(int u,int v,int w,int rw=)
{
edge[tol].to = v;
edge[tol].cap = w;
edge[tol].next = head[u];
edge[tol].flow = ;
head[u] = tol++; edge[tol].to = u;
edge[tol].cap = rw;
edge[tol].next = head[v];
edge[tol].flow = ;
head[v]=tol++;
}
//输入参数:起点、终点、点的总数
//点的编号没有影响,只要输入点的总数
int sap(int start,int end,int N)
{
memset(gap,,sizeof(gap));
memset(dep,,sizeof(dep));
memcpy(cur,head,sizeof(head));
int u=start;
pre[u]=-;
gap[]=N;
int ans=;
while(dep[start]<N)
{
if(u==end)
{
int Min=INF;
for(int i=pre[u]; i!=-; i=pre[edge[i^].to])
if(Min>edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
for(int i=pre[u]; i!=-; i=pre[edge[i^].to])
{
edge[i].flow+=Min;
edge[i^].flow-=Min;
}
u=start;
ans+=Min;
continue;
}
bool flag=false;
int v;
for(int i=cur[u]; i!=-; i=edge[i].next)
{
v=edge[i].to;
if(edge[i].cap-edge[i].flow && dep[v]+==dep[u])
{
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag)
{
u=v;
continue;
}
int Min=N;
for(int i=head[u]; i!=-; i=edge[i].next)
if(edge[i].cap-edge[i].flow && dep[edge[i].to]<Min)
{
Min=dep[edge[i].to];
cur[u]=i;
}
gap[dep[u]]--;
if(!gap[dep[u]])return ans;
dep[u]=Min+;
gap[dep[u]]++;
if(u!=start) u=edge[pre[u]^].to;
}
return ans;
} int main()
{
init();
addedge(u,v,value);
maxf=sap(,n+m+,n+m+); ///源点,汇点,总点数的值。
}

ISAP模板:

#include <cstdio>
#include <cstring> using namespace std; const int MAXN = ;
const int MAXM = ; // ISAP struct edge
{
int t, f;
edge *p, *r;
} T[MAXM], *H[MAXN], *I[MAXN], *P[MAXN]; int C;
int G[MAXN], D[MAXN], L[MAXN]; inline void adde(const int a, const int b, const int c)
{
edge *e1 = T + C++;
edge *e2 = T + C++;
e1->t = b;
e1->f = c;
e1->p = H[a];
e1->r = e2;
H[a] = e1;
e2->t = a;
e2->f = ;
e2->p = H[b];
e2->r = e1;
H[b] = e2;
} inline int isap(const int cnt, const int src, const int snk)
{
int maxf = ;
int curf = 0x3f3f3f3f;
int u = src, v;
edge *e;
memcpy(I, H, sizeof(H));
memset(G, , sizeof(G));
memset(D, , sizeof(D));
G[] = cnt;
while (D[src] < cnt)
{
L[u] = curf;
for (e = I[u]; e; e = e->p)
{
v = e->t;
if (e->f > && D[u] == D[v] + )
{
I[u] = P[v] = e;
if (e->f < curf)
curf = e->f;
u = v;
if (u == snk)
{
maxf += curf;
while (u != src)
{
P[u]->f -= curf;
P[u]->r->f += curf;
u = P[u]->r->t;
}
curf = 0x3f3f3f3f;
}
break;
}
}
if (e)
continue;
if (!--G[D[u]])
break;
int mind = cnt - ;
for (e = H[u]; e; e = e->p)
if (e->f > && D[e->t] < mind)
{
I[u] = e;
mind = D[e->t];
}
++G[D[u] = mind + ];
if (u != src)
{
u = P[u]->r->t;
curf = L[u];
}
}
return maxf;
} int N, M;
bool V[]; int main()
{
int tt, a, b, c, ss, cnt;
scanf("%d", &tt);
for (int tc = ; tc <= tt; ++tc)
{
memset(V, false, sizeof(V));
memset(H, , sizeof(H));
ss = ;
C = ;
scanf("%d%d", &N, &M);
cnt = N + ;
for (int i = ; i < N; ++i)
{
scanf("%d%d%d", &a, &b, &c);
adde(, i, a);
for (int j = b - ; j < c; ++j)
{
adde(i, j + , );
if (!V[j])
{
adde(j + , , M);
V[j] = true;
++cnt;
}
}
ss += a;
}
if (isap(cnt, , ) == ss)
printf("Case %d: Yes\n\n", tc);
else
printf("Case %d: No\n\n", tc);
}
return ;
}

hdu4292 Food 最大流模板题的更多相关文章

  1. HDU-3549 最大流模板题

    1.HDU-3549   Flow Problem 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 3.总结:模板题,参考了 http://ww ...

  2. 【网络流#2】hdu 1533 - 最小费用最大流模板题

    最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...

  3. 【网络流#1】hdu 3549 - 最大流模板题

    因为坑了无数次队友 要开始学习网络流了,先从基础的开始,嗯~ 这道题是最大流的模板题,用来测试模板好啦~ Edmonds_Karp模板 with 前向星 时间复杂度o(V*E^2) #include& ...

  4. POJ 1273 - Drainage Ditches - [最大流模板题] - [EK算法模板][Dinic算法模板 - 邻接表型]

    题目链接:http://poj.org/problem?id=1273 Time Limit: 1000MS Memory Limit: 10000K Description Every time i ...

  5. hdu 1532 Drainage Ditches(最大流模板题)

    Drainage Ditches Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. HDU-3549Flow Problem 最大流模板题

    传送门 这里是Ford-Fulkerson写的最大流模板 #include <iostream> #include <cstdio> #include <algorith ...

  7. POJ-2135 Farm Tour---最小费用最大流模板题(构图)

    题目链接: https://vjudge.net/problem/POJ-2135 题目大意: 主人公要从1号走到第N号点,再重N号点走回1号点,同时每条路只能走一次. 这是一个无向图.输入数据第一行 ...

  8. POJ2135 最小费用最大流模板题

    练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include ...

  9. 2018牛客网暑期ACM多校训练营(第五场) E - room - [最小费用最大流模板题]

    题目链接:https://www.nowcoder.com/acm/contest/143/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...

随机推荐

  1. AD转换器的主要指标

    AD转换器的主要指标如下: (1)分辨率(Resolution).指数字量变化一个最小量时模拟信号的变化量,定义为满刻度与2n的比值.分辨率又称精度,通常以数字信号的位数来表示.定义满刻度于2^n的比 ...

  2. PowerShell Tools for Visual Studio 2015

    首先要去下载Visual Studio 2015 RC 版本 https://www.visualstudio.com/en-us/downloads/visual-studio-2015-downl ...

  3. STM32F407 GPIO 库函数编程套路(led与beep总结) 个人笔记

    本文由正点原子STM32F407探索者开发板的led和beep实验,总结了gpio编程的套路. 下文中以hardware 来称呼可能的硬件外设,如led或beep等. 新建项目后主要用到三个文件:ha ...

  4. Leetcode 174.地下城游戏

    地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. ...

  5. HDU 2442

    状态压缩DP , 和HDU2280极其相似 #include <cstdio> #include <cstring> #include <iostream> usi ...

  6. Codeforces915G. Coprime Arrays

    n<=2e6的数组,m<=2e6个询问,对1<=i<=m的每个i问:只用<=i的数字填进数组,有多少种方案使数组的总gcd=1.强制把每个询问的答案求出来. 比如说现在有 ...

  7. Tomcat服务器调优

    一,目标:优化tomcat来提高访问的并发能力. 服务器提供的内存,cpu,以及硬盘的性能对数据的处理起决定性作用. tomcat的3种运行模式 tomcat的运行模式有3种: 1. bio默认的模式 ...

  8. Android GIS开发系列-- 入门季(10) MapView快速定位到Geometry

    我们知道某个Geometry的坐标,但不知道具体的位置,该如何使地图快速定位呢?这时需要用到MapView.setExtent方法,来看下这个方法的介绍:Zooms the map to the gi ...

  9. 原则 principles

    1.找到对的人来讨论问题. 2.把工作分配给对的人才能把事情做对. 3.

  10. python 进程内存增长问题, 解决方法和工具

    转载:http://drmingdrmer.github.io/tech/programming/2017/05/06/python-mem.html#pyrasite-%E8%BF%9E%E6%8E ...