• poj 3204 Ikki's Story I


    Ikki's Story I - Road Reconstruction

    题意:有N个顶点和M条边N, M (N ≤ 500, M ≤ 5,000)  ,试图改变图中的一条边使得从0到N-1的流量增加;问这样的边有几条?

    思路:刚最大流入门,之后一看就觉得满流的边就是答案。。真是太天真了。之后看了题解,发现满流只是前提(即使满流是几次残量的叠加也是一样),还有一个条件是,该路径的最大流量只受该边影响;即可以从S和T遍历到该边的两个端点,这就是为什么之后还要dfs给点涂色的原因;涂色前要对残余网络中输入的边(反向边不管)标记重建图;

    // 125ms
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<time.h>
    #include<stack>
    #include<set>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    #define inf 0x3f3f3f3f
    #define pb push_back
    #define MK make_pair
    typedef pair<int,int> PII;
    #define A first
    #define B second
    template<typename T>
    void read1(T &m)
    {
        T 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*10+ch-'0';ch=getchar();}
        m = x*f;
    }
    template<typename T>
    void read2(T &a,T &b){read1(a);read1(b);}
    template<typename T>
    void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
    template<typename T>
    void out(T a)
    {
        if(a>9) out(a/10);
        putchar(a%10+'0');
    }
    const int M = 5050;
    const int N = 550;
    int head[M<<1],tot;
    struct edge{
        int from,to,cap,flow,Next;
    }e[M<<1];
    void ins(int u,int v,int cap,int flow)
    {
        e[tot].Next = head[u];
        e[tot].from = u;//为了t->s时由v推到u;
        e[tot].to = v;
        e[tot].cap = cap;
        e[tot].flow = flow;
        head[u] = tot++;
    }
    queue<int> q;
    vector<int> full;
    int p[N];//记录路径中边的标号
    int a[N];//起点到i的可改进量
    void Edmonds_Karp(int s,int t)
    {
        for(;;){
            MS0(a);
            while(!q.empty()) q.pop();
            a[s] = inf;
            q.push(s);
            while(!q.empty()){
                int u = q.front();q.pop();
                for(int id = head[u];~id;id = e[id].Next){
                    int v = e[id].to,c = e[id].cap,f = e[id].flow;
                    if(!a[v] && c > f){
                        p[v] = id;
                        a[v] = min(a[u],c - f);// ** 递推到a[v]
                        q.push(v);
                    }
                }
                if(a[t]) break;
            }
            if(!a[t]) break;
            for(int u = t;u != s;u = e[p[u]].from){
                e[p[u]].flow += a[t];
                e[p[u]^1].flow -= a[t];
                if(e[p[u]].flow == e[p[u]].cap) full.pb(p[u]);
            }
        }
    }
    int color[N],V;
    void DFS(int u,int index)
    {
        if(~color[u]) return ;
        color[u] = index;
        for(int id = head[u];~id;id = e[id].Next){
            if(id&1 || e[id].flow == e[id].cap) continue;//只在原边中找,不看反向边;
            DFS(e[id].to,index);
        }
    }
    int solve()
    {
        MS1(color);
        DFS(0,0);DFS(V-1,1);
        int ans = 0;
        rep0(i,0,full.size()){
            int u = e[full[i]].from, v = e[full[i]].to;
            if(color[u] == 0 && color[v] == 1){
                ans++;
                //out(u);putchar(' ');out(v);puts("bug");
            }
        }
        return ans;
    }
    int main()
    {
        int n,E,kase = 1;
        read2(V,E);
        MS1(head);tot = 0;
        rep0(i,0,E){
            int u,v,w;
            read3(u,v,w);
            ins(u,v,w,0);ins(v,u,0,0);
        }
        Edmonds_Karp(0,V-1);
        out(solve());
        puts("");
        return 0;
    }
    View Code
  • 相关阅读:
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    ajax 几种提交方式
  • 原文地址:https://www.cnblogs.com/hxer/p/5187328.html
Copyright © 2020-2023  润新知