• BZOJ 1797 网络流的可行边&必须边


    求完网络流以后 tarjan一发 判一判

    //By SiriusRen
    #include <queue>
    #include <bitset>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 122222
    int n,m,s,t;
    struct Node{int x,y,w,r;}node[N];
    struct Dinic{
        int first[N],next[N],v[N],w[N],tot,vis[10050];
        int low[N],dfn[N],in[N],stk[N],cnt,top,T,jy,p[N];
        void init(){memset(first,-1,sizeof(first));}
        void add(int x,int y,int z){Add(x,y,z),Add(y,x,0);}
        void Add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
        bool tell(){
            queue<int>q;q.push(s);
            memset(vis,-1,sizeof(vis)),vis[s]=0;
            while(!q.empty()){
                int tp=q.front();q.pop();
                for(int i=first[tp];~i;i=next[i])
                    if(vis[v[i]]==-1&&w[i])
                        vis[v[i]]=vis[tp]+1,q.push(v[i]);
            }
            return vis[t]!=-1;
        }
        int zeng(int x,int y){
            if(x==t)return y;
            int r=0;
            for(int i=first[x];~i&&y>r;i=next[i])
                if(vis[v[i]]==vis[x]+1&&w[i]){
                    int t=zeng(v[i],min(y-r,w[i]));
                    w[i]-=t,w[i^1]+=t,r+=t;
                }
            if(!r)vis[x]=-1;
            return r;
        }
        void flow(){while(tell())while(zeng(s,0x3fffffff));}
        void tarjan(int x){
            dfn[x]=low[x]=++cnt,in[x]=1,stk[++top]=x;
            for(int i=first[x];~i;i=next[i])
                if(w[i]){
                    if(!dfn[v[i]])tarjan(v[i]),low[x]=min(low[x],low[v[i]]);
                    else if(in[v[i]])low[x]=min(low[x],dfn[v[i]]);
                }
            if(low[x]==dfn[x]){T++;do{jy=stk[top--],p[jy]=T,in[jy]=0;}while(jy!=x);}
        }
        void solve(){
            flow();
            for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
            for(int i=1;i<=m;i++){
                if(!w[i*2-2]&&p[node[i].x]==p[s]&&p[node[i].y]==p[t])node[i].w=2;
                else if(p[node[i].x]!=p[node[i].y]&&!w[i*2-2])node[i].w=1;
                else node[i].w=0;
            }
            for(int i=1;i<=m;i++){
                if(node[i].w==2)puts("1 1");
                else if(node[i].w==1)puts("1 0");
                else puts("0 0");
            }
        }
    }dinic;
    int main(){
        dinic.init();
        scanf("%d%d%d%d",&n,&m,&s,&t);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].w);
            dinic.add(node[i].x,node[i].y,node[i].w);
        }
        dinic.solve();
    }

    这里写图片描述

  • 相关阅读:
    android4.0 及以上 版本 wifi 和 蓝牙不显示 原因
    AWK命令使用 小结
    Linux xargs命令 小结
    nginx rewrite伪静态配置参数详细说明
    简评file_get_contents与curl 效率及稳定性
    zendstudio 常用快捷键
    PHP字符串三种定义方式
    PHP连贯接口
    yii学习笔记
    PHP中str_replace函数的详解
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532129.html
Copyright © 2020-2023  润新知