标签:name pop eve 网络 时间复杂度 using cout eof dinic
一句话题意:给出一个网络图,以及其源点和汇点,求出其网络最大流
//dinic算法;
//时间复杂度O(V^2E);
#include<bits/stdc++.h>
#define inf 999999
#define maxn 200000
using namespace std;
int n,m,s,t;
int ans=0;
struct Edge
{
int to,next,w;
};
struct Edge edge[maxn];
int head[maxn],val[maxn],pre[maxn];
int level[maxn];
int cnt=0;
void add(int u,int v,int w)//前向星储存边
{
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
int bfs(int s,int t)
{
queue<int> q;
q.push(s);
memset(level,-1,sizeof(level));//一定要从-1开始储存,如果从0开始存的话由于数组本身就是0,会造成死循环!!
level[s]=0;
while(!q.empty())
{
int j=q.front();q.pop();
for(int i=head[j];~i;i=edge[i].next)
{
int v=edge[i].to;
if(level[v]==-1&&edge[i].w)//染色,广搜求出到达每个点的步数
{
level[v]=level[j]+1;
q.push(v);
}
}
}
return (level[t]==-1) ? 0 : 1;//如果不能达到t就是没有增广路,就不进行查找
}
int dfs(int u,int flow,int v)
{
if(u==v)
return flow;
int rest=0;
for(int i=head[u];~i;i=edge[i].next)
{
int j=edge[i].to;
if(level[u]+1==level[j]&&edge[i].w)
{
int flo=dfs(j,min(edge[i].w,flow-rest),v);
rest+=flo;
edge[i].w-=flo;
edge[i^1].w+=flo;//如果i=0,则去i+1如果i=1则取0,总之是取反向边
}
}
if(!rest)
level[u]=-1;
return rest;
}
int main()
{
int u,v,w;
memset(head,-1,sizeof(head));
cin>>n>>m>>s>>t;
for(int i=0;i<m;i++)//注意从0开始储存,否则会发生错误
{
cin>>u>>v>>w;
add(u,v,w);//s->t存到2k
add(v,u,0);//t->s存到2k-1
}
while(bfs(s,t))
while(int tmp=dfs(s,inf,t))
ans+=tmp;
cout<<ans<<endl;
return 0;
}
标签:name pop eve 网络 时间复杂度 using cout eof dinic
原文地址:http://www.cnblogs.com/foreverpiano/p/6910324.html