哔哩哔哩 @ 2018-12-23 00:11:31
刚接触dinic
不是很懂优化
求大佬帮忙
//Dinic
#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define INF 0x3fffffff
inline int read() {
int x = 0,f = 1;
char ch = getchar();
while(ch<'0'||ch>'9') { if(ch=='-') f = -1; ch = getchar(); }
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x * f;
}
struct point{
int fr,to,val;
int nxt;
}edge[N];
int cur[N];//听说可以弧优化
int head[N];
int cnt;
void add_edge(int x,int y,int z)
{
edge[cnt].fr=x,edge[cnt].to=y,edge[cnt].val=z;
edge[cnt].nxt=head[x],head[x]=cnt++;
edge[cnt].fr=y,edge[cnt].to=x,edge[cnt].val=0;
edge[cnt].nxt=head[y],head[y]=cnt++;
}
//我放弃链式前向星
int n,m,st,ed;
int deep[N];
int BFS()
{
queue<int>q;
for(int i=0;i<=n;i++) cur[i]=head[i],deep[i]=0;
q.push(st);
deep[st]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=edge[i].nxt)
{
int tmp=edge[i].to;
if(edge[i].val<=0 || deep[tmp]) continue;
deep[tmp]=deep[u]+1;
q.push(tmp);
}
}
return deep[ed];
}
int ans;
int dfs(int u,int flow)//flow为到达终点最多能增广的值
{
if(u==ed) return flow;
int add=0;
for(int i=cur[u];i!=-1&&add<flow;i=edge[i].nxt)
{
cur[u]=i;
int v=edge[i].to;
if(deep[v]!=deep[u]+1) continue;
if(!edge[i].val) continue;//剪枝
int tmpadd=dfs(v,min(edge[i].val,flow-add));
edge[i].val-=tmpadd;
edge[i^1].val+=tmpadd;//sub
add+=tmpadd;
}
return add;
}
void Dinic()
{
while(BFS()) ans+=dfs(st,INF);
}
int main()
{
n=read(),m=read(),st=read(),ed=read();
memset(head,-1,sizeof(head));
for(int i=1,u,v,co;i<=m;i++)
{
u=read(),v=read(),co=read();
add_edge(u,v,co);
}
Dinic();
printf("%d\n",ans);
return 0;
}
by info___tion @ 2018-12-23 00:16:37
当前弧优化啊
by 哔哩哔哩 @ 2018-12-23 00:18:27
@info___tion 不是很懂,求请教(不知道我的cur是不是写错了)
by Sai0511 @ 2018-12-23 00:22:01
@哔哩哔哩 表示ek过了。。应该是你写错了吧
by info___tion @ 2018-12-23 00:22:22
@哔哩哔哩 你这代码的问题似乎有些大……
by info___tion @ 2018-12-23 00:23:08
首先,Dinic的层次图貌似不能清零(不然好像会错),所以我看到你那个deep数组清零的时候……
by info___tion @ 2018-12-23 00:29:46
当前弧优化就是在DFS里面枚举增广路上的边时,把你那个cur数组拉进循环里面再加个引用。
应该是这样:
for(int& i=cur[u];
然后每次BFS完都要把cur清零(如果是链式前向星就令cur[i]=Head[i](就是链表的头指针))
在你的代码里面应该是这样:
while(BFS())
{
for(int i=1;i<=n;i++)
cur[i]=head[i];
ans+=dfs(st,INF);
}