【模板】【网络流】【网络最大流】FF,bfs,dinic

之前写好的网络流笔记没有保存,不见了,懒得弄了,直接贴代码了

什么时候闲了再回来搞吧

//科学计数法:2e9 
//1dfs 
//其实我是有一点拿网络流练dfs的意思的 
#include<cstdio>
#include<cstdlib>
#include<algorithm> 
#include<cstring>
using namespace std;
const int inf=2e9; 
int n,m,s,ed;//明确了以后用ed表示终点 
const int N=10003,M=100003;//这里主要看N的大小,N不大就用邻接矩阵,N太大N^2就会MLE,用邻接表
int head[N],tot=1; 
struct node
{
    int v,w,nx;
}e[M<<1];//双向边
void add(int u,int v,int w)
{
    e[++tot].v =v,e[tot].w =w,e[tot].nx =head[u],head[u]=tot;
    e[++tot].v =u,e[tot].w =0,e[tot].nx =head[v],head[v]=tot;//这里把反向边的值设置成0,防止反向走边 
}

bool vis[N];
int dfs(int x,int flow)
{
    for(int i=head[x];i;i=e[i].nx )
    {
        int v=e[i].v ,w=e[i].w ;
        
        if(vis[v] || w<=0) continue;
        
        vis[v]=true;
        int t=min(flow,w),tt;
        if(v==ed) 
        {
            e[i].w -=t,e[i^1].w +=t;
            return t;
        }
        else if( (tt=dfs(v,t))>0  )//夭寿咯 
        {
            e[i].w -=tt;
            e[i^1].w +=tt;
            return tt;
        }
    }
    return 0;
}

int ans;
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&ed);
    int u,v,w;
    while(m--)
        scanf("%d%d%d",&u,&v,&w),add(u,v,w);
    //练习dfs剪枝啦~~ 
    int ttt=0;
    while((memset(vis,false,sizeof(vis)) &&(vis[s]=true) ) && ( ttt=dfs(s,inf))>0)//夭寿咯 
        ans+=ttt; 
    printf("%d",ans);
    
    return 0;
} 
//FF算法 
//1    dfs 1.09s 
//2    bfs 330s
#include<cstdio>
#include<cstdlib>
#include<algorithm> 
#include<cstring>
#include<queue>
using namespace std;
const int inf=2e9; 
int n,m,s,ed;//明确了以后用ed表示终点 
const int N=10003,M=100003;//这里主要看N的大小,N不大就用邻接矩阵,N太大N^2就会MLE,用邻接表
int head[N],tot=1; 
struct node
{
    int v,w,nx;
}e[M<<1];//双向边
void add(int u,int v,int w)
{
    e[++tot].v =v,e[tot].w =w,e[tot].nx =head[u],head[u]=tot;
    e[++tot].v =u,e[tot].w =0,e[tot].nx =head[v],head[v]=tot;//这里把反向边的值设置成0,防止反向走边 
}

int pre[N];//作用更大的vis标记
int flow[N];//没有dfs一整条路径来记,每个点的flow只能自己记着 
int ans;
void bfs()
{
    queue <int> q;
    while(1)
    {
        memset(pre,0,sizeof(pre));
        memset(flow,0,sizeof(flow));//清空 
        //找边 
        pre[s]=-1,flow[s]=inf;//这里的pre不能是0,否则会被遍历到 //flow依旧设成无限大 
        while(!q.empty() ) q.pop() ;
        q.push(s); 
        while(!flow[ed] && !q.empty() )
        {
            int u=q.front() ;q.pop() ;
            for(int i=head[u];i;i=e[i].nx )
            {
                int v=e[i].v ;
                if(!flow[v] && e[i].w >0)
                    pre[v]=i,flow[v]=min(flow[u],e[i].w ),q.push(v); 
            }
        } 
        if(!flow[ed]) break;
        //没有增广路就退出
        ans+=flow[ed];
        int pos=pre[ed],tt=flow[ed];
        while( pos >0)//注意!!!夭寿咯 
        {
            e[pos].w -=tt;
            e[pos^1].w +=tt;
            pos=pre[e[pos^1].v ];
        }
    }  
    printf("%d",ans);
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&ed);
    int u,v,w;
    while(m--)
        scanf("%d%d%d",&u,&v,&w),add(u,v,w);
    //bfs加速搜索啦~~ 
    bfs();
    
    return 0;
} 
//3dinic 154ms
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cstring>
using namespace std;
int n,m,s,ed;
const int N=10003,M=100003,inf=2e9;
struct node
{ int v,w,nx; }e[M<<1];
int tot=1,head[N];
void add(int u,int v,int w)
{ e[++tot].v =v,e[tot].w =w,e[tot].nx =head[u],head[u]=tot; }

int cur[N],dep[N],depth;
int bfs()
{
    memset(dep,0,sizeof(dep));
    dep[s]=1;
    queue <int> q;
    q.push(s);
     
    while(!dep[ed] && !q.empty() )
    {
        int u=q.front() ;q.pop() ;
        for(int i=head[u];i;i=e[i].nx )
        {
            int v=e[i].v ;
            if(!dep[v] && e[i].w >0)
                dep[v]=dep[u]+1,q.push(v); 
        }
    }
    return depth=dep[ed];
}
int dfs(int x,int flow)
{
    int ans=0;
    if(x==ed) return flow;
    if(!dep[x] || dep[x]>depth) return 0;
    for(int i=head[x];i;i=e[i].nx )
    {
        int v=e[i].v ;
        if(dep[v]==dep[x]+1 && e[i].w >0)
        {
            int t=dfs(v,min(flow,e[i].w ));
            e[i].w -=t;
            e[i^1].w +=t; 
            flow-=t,ans+=t;
        }
        if(!flow) break;
    }
    if(!ans) dep[x]=0;
    return ans;
}

int aans;
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&ed);
    int u,v,w;
    while(m--)
        scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,0);
    
    while(bfs())
        aans+=dfs(s,inf);
    printf("%d\n",aans);
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xwww666666/p/11296828.html