• [AHOI2009]最小割


    大概意思是让求一个图的最小割的必须边和可行边

    然后做法就是在残量网络上跑tarjan缩点。如果这个边没有满流,它就没有被割,肯定不是。

    如果这个边的from和to不在一个点,就是可行边。如果from和S在一起,to和T在一起,就是必须边。

    jcvb:(策神Orz

    在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号。显然有id[s]!=id[t](否则s到t有通路,能继续增广)。

    ①对于任意一条满流边(u,v),(u,v)能够出现在某个最小割集中,当且仅当id[u]!=id[v];
    ②对于任意一条满流边(u,v),(u,v)必定出现在最小割集中,当且仅当id[u]==id[s]且id[v]==id[t]。

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    int n,m,S,T,ecnt=1;
    const int M=120005,N=40005;
    struct Edge{
        int from,to,nxt,val;
    }e[M];
    int h[N],maxflow,head[N];
    inline void add(int bg,int ed,int val) {
        e[++ecnt]=(Edge){bg,ed,head[bg],val};head[bg]=ecnt;
    }
    bool bfs() {
        queue<int>q;
        q.push(S);
        memset(h,-1,sizeof (int)*(n+4));
        h[S]=0;
        while(!q.empty()) {
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].nxt) {
                int v=e[i].to;
                if(h[v]==-1&&e[i].val) {
                    h[v]=h[u]+1;q.push(v);
                }
            }
        }
        return h[T]!=-1;
    }
    int dfs(int x,int f) {
        if(x==T) return f;
        int used=0,tp;
        for(int i=head[x];i;i=e[i].nxt) {
            int v=e[i].to;
            if(e[i].val&&h[x]+1==h[v]) {
                tp=dfs(v,min(e[i].val,f-used));
                used+=tp;
                e[i].val-=tp;
                e[i^1].val+=tp;
                if(used==f) return used;
            }
        }
        if(used==0) h[x]=-1;
        return used;
    }
    void dinic() {while(bfs())dfs(S,0x3f3f3f3f);}
    int stk[N],top,id[N],low[N],dfn[N],tim,tot;
    bool vis[N];
    void tarjan(int x) {
        low[x]=dfn[x]=++tim;vis[x]=1;stk[++top]=x;
        for(int i=head[x];i;i=e[i].nxt) {
            int v=e[i].to;
            if(!e[i].val) continue;
            if(!dfn[v]) {
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if(vis[v]) low[x]=min(low[x],dfn[v]);
        }
        if(dfn[x]==low[x]) {
            id[x]=++tot;vis[x]=0;
            while(stk[top]!=x) {
                id[stk[top]]=tot;vis[stk[top]]=0;
                top--;
            }
            top--;
        }
    }
    int main() {
        scanf("%d%d%d%d",&n,&m,&S,&T);
        for(int i=1,a,b,c;i<=m;i++) scanf("%d%d%d",&a,&b,&c),add(a,b,c),add(b,a,0);
        dinic();
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
        for(int i=2;i<=ecnt;i+=2) {
            if(e[i].val) {puts("0 0");continue;}
            if(id[e[i].from]!=id[e[i].to])
                putchar('1');
            else {puts("0 0");continue;}
            putchar(' ');
            if(id[S]==id[e[i].from]&&id[T]==id[e[i].to]) puts("1");else puts("0");
            
        }
    }
    最小割
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    JSON数据的中文乱码问题
    使用json-lib进行Java和JSON之间的转换
    struts2 struts.xml配置文件详解
    php位运算的应用(转)
    oracle数据库导入导出的dmp(转)
    Java多线程-工具篇-BlockingQueue(转)
    javaweb之Filter详解(转)
    MYSQL写入数据时报错ERROR 1366 (HY000): Incorrect string value: 'xE8x8BxB1xE5xAFxB8...' for c 插入中文不能插入
    插入中文错误ERROR 1406 (22001): Data too long for column 'name' at row 1
    SQL语句处理一些修改、新增、删除、修改属性操作(MySql)
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9732124.html
Copyright © 2020-2023  润新知