网络最大流dinic
P3376【模板】网络最大流
在全机房的共同努力下搞出来的
假的写法
实测836ms比EK还慢
(来自Blueqwq)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cstring>
#define maxn 210
#define maxm 10010
#define int long long
using namespace std;
template<typename T>
inline void read(T &x){
x=0; bool flag=0; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
for(;isdigit(c);c=getchar()) x=x*10+(c^48);
if(flag) x=-x;
}
const int inf=1e18;
int n,m,s,t,u,v,w;
int ans=0,cnt,head[maxn],dep[maxn],now[maxn],depth,lim;
bool vis[maxn];
struct node{
int nxt;
int to;
int v;
}e[maxm];
void add(int from,int to,int v){
e[cnt].to=to;
e[cnt].nxt=head[from];
e[cnt].v=v;
head[from]=cnt++;
}
bool bfs(){
memset(dep,0,sizeof(dep));
memset(vis,0,sizeof(vis));
queue<int>q;
q.push(s);
dep[s]=1;
vis[s]=true;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i!=-1;i=e[i].nxt){
int y=e[i].to,v=e[i].v;
if(v&&!vis[y]){
vis[y]=1;
dep[y]=dep[x]+1;
q.push(y);
}
}
}
return vis[t];
}
int dfs(int x,int lim){
if(x==t) return lim;
int res=0;//res必为局部变量,因为如果是全局变量,中间就清零了,返回值就奇奇怪怪,可能会有负数
for(int i=head[x];i!=-1;i=e[i].nxt){
int y=e[i].to,v=e[i].v;
if(v&&dep[y]>dep[x]){
int flow=dfs(y,min(v,lim));//因为这里还要dfs的
e[i].v-=flow;
e[i^1].v+=flow;
res+=flow;
lim-=flow;
}
}
if(res==0) dep[x]=0;
return res;
}
int dinic(){
while(bfs()) ans+=dfs(s,inf);
return ans;
}
signed main(){
read(n),read(m),read(s),read(t);
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++){
read(u),read(v),read(w);
add(u,v,w);
add(v,u,0);
}
cout<<dinic()<<endl;
return 0;
}
orz XiEn1847,orz Blueqwq
真的写法1
实测57ms
(来自AWR2020)
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 5010;
const long long inf = 0x0fffffffffffffff;
int n, m, s, t;
int ct = 1, hd[N], ver[N<<1], nxt[N<<1]; ll wt[N<<1];
int dep[N]; bool inque[N];
int cur[N];
void add(int u, int v, ll w) {
ct ++;
ver[ct] = v;
wt[ct] = w;
nxt[ct] = hd[u];
hd[u] = ct;
ct ++;
ver[ct] = u;
wt[ct] = 0;
nxt[ct] = hd[v];
hd[v] = ct;
}
bool bfs() {
memset(dep, 0x3f, sizeof(dep));
memset(inque, 0, sizeof(inque));
queue<int> q;
q.push(s);
dep[s] = 0;
cur[s] = hd[s];
inque[s] = true;
while(q.size()) {
int x = q.front();
q.pop();
inque[x] = false;
for(int i = hd[x]; i; i = nxt[i]) {
int y = ver[i];
if(wt[i] && dep[y] > dep[x] + 1) {
dep[y] = dep[x] + 1;
cur[y] = hd[y];
if(!inque[y]) {
q.push(y);
inque[y] = true;
}
}
}
}
if(dep[t] != 0x3f3f3f3f)
return true;
return false;
}
ll dfs(int x, ll flow) {
ll ret = 0;
if(x == t)
return flow;
for(int i = cur[x]; i; i = nxt[i]) {
cur[x] = i;
int y = ver[i];
if(wt[i] && dep[y] == dep[x] + 1) {
if(ret = dfs(y, min(flow, wt[i]))) {
wt[i] -= ret;
wt[i^1] += ret;
return ret;
}
}
}
return 0;
}
ll dinic() {
ll maxflow = 0, flow;
while(bfs())
while(flow = dfs(s, inf))
maxflow += flow;
return maxflow;
}
int main() {
cin >> n >> m >> s >> t;
for(int i = 1; i <= m; i ++) {
int u, v; ll w;
scanf("%d%d%lld", &u, &v, &w);
add(u, v, w);
}
cout << dinic() << endl;
return 0;
}
orz AWR2020
真的写法2
实测54ms
(来自lhm_)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cstring>
#define maxn 10010
#define maxm 200010
#define int long long
using namespace std;
template<typename T>
inline void read(T &x){
x=0; bool flag=0; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
for(;isdigit(c);c=getchar()) x=x*10+(c^48);
if(flag) x=-x;
}
const int inf=1e18;
int n,m,s,t,u,v,w;
int ans,cnt=1,head[maxn],dep[maxn],cur[maxn],depth,lim,res;//pay attention! ans=1!!!
struct node{
int nxt;
int to;
int v;
}e[maxm];
void add(int from,int to,int v){
e[++cnt].to=to;
e[cnt].nxt=head[from];
head[from]=cnt;
e[cnt].v=v;
}
bool bfs(){
memcpy(cur,head,sizeof(head));//********
memset(dep,0,sizeof(dep));
queue<int>q;
q.push(s);
dep[s]=1;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to,v=e[i].v;
if(!v||dep[y]) continue;
dep[y]=dep[x]+1;
q.push(y);
}
}
return dep[t];
}
int dfs(int x,int lim){
if(x==t) return lim;
int res=lim,flow;
for(int &i=cur[x];i;i=e[i].nxt){//当前弧优化,cur会和i一起改
int y=e[i].to,v=e[i].v;
if(!v||dep[y]!=dep[x]+1) continue;
flow=dfs(y,min(v,res));
res-=flow;
e[i].v-=flow;
e[i^1].v+=flow;
if(res<=0) break;
}
return lim-res;
}
/*
int dfs(int x,int lim){
if(x==t) return lim;
int res=lim,flow;
for(int i=cur[x];i;i=e[i].nxt){//和上面的写法等效
cur[x]=i;
int y=e[i].to,v=e[i].v;
if(!v||dep[y]!=dep[x]+1) continue;
flow=dfs(y,min(v,res));
res-=flow;
e[i].v-=flow;
e[i^1].v+=flow;
if(res<=0) break;
}
return lim-res;
}
*/
int dinic(){
while(bfs()) while(int flow=dfs(s,inf)) ans+=flow;
return ans;
}
signed main(){
read(n),read(m),read(s),read(t);
for(int i=1;i<=m;i++){
read(u),read(v),read(w);
add(u,v,w);
add(v,u,0);
}
cout<<dinic()<<endl;
return 0;
}
orz lhm_,orz i207M,orz AWR2020,orz XiEn1847,orz wsy_jim