hdu4292 Food 最大流模板题
题目链接: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 最大流模板题的更多相关文章
- HDU-3549 最大流模板题
1.HDU-3549 Flow Problem 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 3.总结:模板题,参考了 http://ww ...
- 【网络流#2】hdu 1533 - 最小费用最大流模板题
最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...
- 【网络流#1】hdu 3549 - 最大流模板题
因为坑了无数次队友 要开始学习网络流了,先从基础的开始,嗯~ 这道题是最大流的模板题,用来测试模板好啦~ Edmonds_Karp模板 with 前向星 时间复杂度o(V*E^2) #include& ...
- POJ 1273 - Drainage Ditches - [最大流模板题] - [EK算法模板][Dinic算法模板 - 邻接表型]
题目链接:http://poj.org/problem?id=1273 Time Limit: 1000MS Memory Limit: 10000K Description Every time i ...
- hdu 1532 Drainage Ditches(最大流模板题)
Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU-3549Flow Problem 最大流模板题
传送门 这里是Ford-Fulkerson写的最大流模板 #include <iostream> #include <cstdio> #include <algorith ...
- POJ-2135 Farm Tour---最小费用最大流模板题(构图)
题目链接: https://vjudge.net/problem/POJ-2135 题目大意: 主人公要从1号走到第N号点,再重N号点走回1号点,同时每条路只能走一次. 这是一个无向图.输入数据第一行 ...
- POJ2135 最小费用最大流模板题
练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include ...
- 2018牛客网暑期ACM多校训练营(第五场) E - room - [最小费用最大流模板题]
题目链接:https://www.nowcoder.com/acm/contest/143/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...
随机推荐
- 集训第四周(高效算法设计)D题 (区间覆盖问题)
原题 UVA10020 :http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19688 经典的贪心问题,区间上贪心当然是右区间越 ...
- Ajax的特点
[传统提交方式] 客户端提交请求后,服务器会找到相应的资源进行执行.并将执行结果重新发送给客户端.客户端接收到服务器端的响应会进行重新解释并显示.此时的页面是一个全新的页面. [Ajax提交] 客户端 ...
- Selenium IDE-自动化实战
1.输入测试 Base URL 2.打开录制按钮(默认是录制状态,点击一下就是停止,再次点击,又继续录制) 3.在浏览器界面进行相关操作(比如输入selenium,点击搜索按钮,查看搜索结果),之后点 ...
- Leetcode 220.存在重复元素III
存在重复元素III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. ...
- 60. Spring Boot写后感【从零开始学Spring Boot】
从2016年4月15日到2016年7月20日经历长达3个月的时间,[从零开始学习Spring Boot]系列就要告一段落了.国内的各种资源都比较乱或者是copy 来copy去的,错了也不加以修正下,导 ...
- [luoguP1082] 同余方程(扩展欧几里得)
传送门 ax≡1(mod b) 这个式子就是 a * x % b == 1 % b 相当于 a * x - b * y == 1 只有当 gcd(a,b) == 1 时才有解,也就是说 ax + by ...
- uva10537 最短路 倒推
题意:知道了,最后需要的,那么就倒着最短路,推出去就可以了. 以最短路的方式来解决.
- ie下php session不能用(域名的合法定义)
今天遇到了一个奇怪的问题.应用程序的后台ie下居然无法登陆,老是提示验证码不正确,明明输入是正确的.于是抓包.测试.调试,最终发现罪魁祸首phpsessionid在ie下没有办法写入.研究了一下,发现 ...
- Binary Tree Postorder Traversal(各种非递归实现,完美利用栈结构模拟)
1.后序遍历的非递归实现.(左右根) 难点:后序遍历的非递归实现是三种遍历方式中最难的一种.因为在后序遍历中,要保证左孩子和右孩子都已被访问并且左孩子在右孩子前访问才能访问根结点,这就为流程的控制带来 ...
- 安装adt-bundle-windows-x86-20130917时遇到的问题及解决方法
最近在上安卓课,老师让我们下载此软件(adt-bundle-windows-x86-20130917.下载压缩后,打开eclipse的时候,会出现以下情况: 这时说明你的jdk还没下载或者下载错位置了 ...