topic
Ideas
Pre-flow advances the board.
Dinic, EK, and FF are all the same idea, namely cancellation, this algorithm is no exception, but the idea of this algorithm is to introduce the concept of height like ISAP, in the process for each node to fill up the flow, each point If there is an excess flow , as long as there is only s in the network and the excess flow of t is not 0, it is a set of solutions.
code:
#include<iostream>
#include<stack>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<vector>
#include<list>
#include<map>
#include<queue>
#include<deque>
#define inf 0x3f3f3f3f
using namespace std;
int x,y,w;
struct f{
int to,net,w;
} a[2000016];
int head[10001],gap[10001],h[10001],cel[10001];
bool vis[10001];
int n,m,s,t,tot;
struct cmp{
bool operator ()(int x,int y)const
{
return h[x]<h[y];
}
};
priority_queue<int,vector<int>,cmp > u;
queue<int> p;
void add(int x,int y,int w)
{
a[tot].to=y;
a[tot].w=w;
a[tot].net=head[x];
head[x]=tot;
tot++;
return;
}
bool bfs()
{
memset(h+1,inf,sizeof(int)*n);
h[t]=0;
p.push(t);
while (p.size())
{
int o=p.front();
p.pop();
for (int i=head[o];i!=-1;i=a[i].net)
{
if (a[i^1].w!=0&&h[a[i].to]>h[o]+1)
{
h[a[i].to]=h[o]+1;
p.push(a[i].to);
}
}
}
return h[s]!=inf;
}
void push(int x)
{
for (int i=head[x];i!=-1;i=a[i].net)
{
if (a[i].w&&h[x]==h[a[i].to]+1)
{
int temp=min(cel[x],a[i].w);
a[i].w-=temp;
a[i^1].w+=temp;
cel[x]-=temp;
cel[a[i].to]+=temp;
if (a[i].to!=s&&a[i].to!=t&&vis[a[i].to]==0)
{
vis[a[i].to]=1;
u.push(a[i].to);
}
}
if (cel[x]==0) break;
}
return;
}
void relabel(int x)
{
h[x]=inf;
for (int i=head[x];i;i=a[i].net)
{
if (a[i].w!=0&&h[a[i].to]+1<h[x]) h[x]=h[a[i].to]+1;
}
return;
}
int hlpp()
{
if (!bfs()) return 0;
h[s]=n;
memset(gap,0,sizeof(int)*(n<<1));
for (int i=1;i<=n;i++) if (h[i]!=inf) gap[h[i]]++;
for (int i=head[s];i!=-1;i=a[i].net)
{
if (a[i].w)
{
int temp=a[i].w;
a[i].w-=temp;
a[i^1].w+=temp;
cel[s]-=temp;
cel[a[i].to]+=temp;
if (a[i].to!=s&&a[i].to!=t&&vis[a[i].to]==0)
{
vis[a[i].to]=1;
u.push(a[i].to);
}
}
}
while (u.size())
{
int o=u.top();
u.pop();
vis[o]=0;
push(o);
if (cel[o])
{
gap[h[o]]--;
if (!gap[h[o]])
{
for (int i=1;i<=n;i++)
{
if (i!=s&&i!=t&&h[i]>h[o]&&h[i]<n+1) h[i]=n+1;
}
}
relabel(o);
gap[h[o]]++;
u.push(o);
vis[o]=1;
}
}
return cel[t];
}
signed main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
memset(head,-1,sizeof(head));
for (int i=1;i<=m;i++)
{
long long w;
scanf("%d%d%lld",&x,&y,&w);
add(x,y,w);
add(y,x,0);
}
long long uu=hlpp();
printf("%lld",uu);
return 0;
}