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 ...
随机推荐
- 集训第四周(高效算法设计)B题 (二分查找优化题)
---恢复内容开始--- Description Before the invention of book-printing, it was very hard to make a copy of ...
- Python基础—线程、进程和协程
今天已是学习Python的第十一天,来干一碗鸡汤继续今天的内容,今天的鸡汤是:超越别人对你的期望.本篇博客主要介绍以下几点内容: 线程的基本使用: 线程的锁机制: 生产者消费之模型(队列): 如何自定 ...
- Python之条件 循环和其他语句 2014-4-6
#条件 循环和其他语句 23:30pm-1:431.print和import的更多信息 使用逗号将多个表达式输出 >>> print 'age:',42 age: 42 >&g ...
- Git 与其他系统 - Git 与 Subversion
https://git-scm.com/book/zh/v1/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-Git-%E4%B8%8E-Subve ...
- 【最大流】Escape
https://www.bnuoj.com/v3/contest_show.php?cid=9149#problem/F [题意] 给定n个人和m个星球,每个人可以匹配某些星球,每个星球有一定的容量限 ...
- 静态区间第k大(划分树)
POJ 2104为例[经典划分树问题] 思想: 利用快速排序思想, 建树时将区间内的值与区间中值相比,小于则放入左子树,大于则放入右子树,如果相等则放入左子树直到放满区间一半. 查询时,在建树过程中利 ...
- P1230 智力大冲浪 洛谷
https://www.luogu.org/problem/show?pid=1230 题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每 ...
- spring 数据源JNDI 基于tomcat mysql配置
关键代码 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean&q ...
- ibatis中isNotNull与isNotEmpty区别
isNotNull:参数不能为null,空的可以的 isNotEmpty:参数不能为null和空 那什么是空?比如String类型 String a = ""; a就是空
- sata express接口
华硕z97主板的sata express接口目前没什么用,但随着电脑接口的发展,可能会占据一席之地. 1.顾名思义,SATA-Express是SATA接口 + PCI-Express的混合体,其理论带 ...