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 ...
随机推荐
- 关于解决ssh的"Write failed: Broken pipe"问题
操作环境: 服务器:微软云 Linux CentOS 虚拟机 客户端:MAC OSX terminal 问题描述: 登录虚拟机短时间内不操作就会断开连接并报该“Write failed: Broken ...
- TCP传输的三次握手四次挥手策略
为了准确无误地数据送达目标处,TCP协议采用了三次握手策略.用TCP协议把数据包送出去后,TCP不会对传送后的情况置之不理,它一定会向对方确认是否成功送达.握手中使用了TCP的标志:SYN和ACK 发 ...
- xcap发包工具的简单使用2(发送报文)
上一篇文章介绍了如何构造报文,现在简单讲一下发送报文的步骤 1.获取接口列表 点击主界面工具栏中的“刷新列表”按钮(或对应菜单“interface->Reference interfaces”) ...
- [luoguP2401] 不等数列
传送门 f[i][j]表示前i个数有j个<的方案数 #include <cstdio> #define N 1001 #define p 2015 int n, k; int f[N ...
- android源码mm时的编译错误no ruler to make target `out/target/common/obj/JAVA_LIBRARIES/xxxx/javalib.jar', needed by `out/target/common/obj/APPS/xxxx_intermediates/classes-full-debug.jar'. Stop.
瞧见没有,就因为多了这一个反斜杠,浪费了一下午时间找问题,哭了~~~~
- bzoj2212 Tree Rotations
被BZOJ坑了一下午,原以为是我程序有问题一直WA,结果是我数组小了...为啥不给我RE!!! 线段树合并,对于逆序对而言,只能通过交换左右子树来达到,那么我们就可以想到对于一个结点而言,我们当然要取 ...
- 牛腩新闻系统(一)——UML、数据库设计
牛腩新闻系统(一)--UML.数据库设计 一.初识牛腩系统 牛腩(Brisket)即牛腹部及靠近牛肋处的松软肌肉,是指带有筋.肉.油花的肉 块.这是一种统称. 若依部位来分,牛身上很多地方的肉都能够叫 ...
- Linux 中浏览网页的命令行
Linux系统环境的WEB网站浏览器工具,常用的有w3m.Links.Lynx三个工具 第一.w3m w3m文本浏览器是基于GPL协议发布的且支持表格.颜色.SSL连接以及内链图像,因速度快而著称. ...
- python实现同服站点地址获取
说明:程序使用http://s.tool.chinaz.com/same此站点查询的结果.使用python简单的实现抓取结果 先随便查询一个结果,抓包分析,如图: 使用python模仿post表单,使 ...
- 【LeetCode-面试算法经典-Java实现】【067-Add Binary(二进制加法)】
[067-Add Binary(二进制加法)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given two binary strings, return thei ...