网络最大流 复习

眉间皱痕 提交于 2019-12-04 13:38:14

打板子 调了\(2\)h 无语了

\(EdmondKarp+Dinic(Dinitz)\)

#include <set>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define reg register int
#define isdigit(x) ('0' <= x&&x <= '9')
template<typename T>
inline T Read(T Type)
{
    T x = 0,f = 1;
    char a = getchar();
    while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    return x * f;
}
const int MAXN = 10010,MAXM = 100010;
int cnt,n,m,s,t,_ori[MAXN];
struct EDGE
{
    int v,w,_nxt;
    EDGE() {v = w = _nxt = 0;}
}edge[MAXM << 1];
inline void addedge(int u,int v,int w)
{
    edge[++cnt]._nxt = _ori[u];
    edge[cnt].v = v;
    edge[cnt].w = w;    
    _ori[u] = cnt;
}
inline void add(int u,int v,int w) {addedge(u,v,w),addedge(v,u,0);}
namespace EdmondKarp
{
    const int inf = 0x7f7f7f7f;
    struct Path {int v,e;}pre[MAXN];
    bool vis[MAXN];
    inline bool Bfs(int s,int t)
    {
        memset(vis,0,sizeof(vis));
        memset(pre,0,sizeof(pre));
        queue<int> q;
        q.push(s),vis[s] = 1;
        while(!q.empty())
        {
            int v,tp = q.front();q.pop();
            if(tp == t) return true;
            for(reg e = _ori[tp];e;e = edge[e]._nxt)
                if(!vis[v = edge[e].v]&&edge[e].w)
                {
                    pre[v].v = tp,pre[v].e = e;
                    if(v == t) return true;
                    vis[v] = 1,q.push(v);
                }
        }
        return false;
    }
    inline int EK(int s,int t)
    {
        int ans = 0;
        while(Bfs(s,t))
        {
            int flow_ = inf;
            for(reg i = t;i != s;flow_ = min(flow_,edge[pre[i].e].w),i = pre[i].v);
            for(reg i = t;i != s;edge[pre[i].e].w -= flow_,edge[pre[i].e ^ 1].w += flow_,i = pre[i].v);
            ans += flow_;
        }
        return ans;
    }
}
namespace Dinitz
{
    const int inf = 0x7f7f7f7f;
    int depth[MAXN],fire[MAXN];
    inline bool Bfs(int s,int t)
    {
        memset(depth,-1,sizeof(depth));
        queue<int> q;
        q.push(s),depth[s] = 0;
        while(!q.empty())
        {
            int v,tp = q.front();q.pop();
            for(reg e = _ori[tp];e;e = edge[e]._nxt)
                if(depth[v = edge[e].v] == -1&&edge[e].w)
                    depth[v] = depth[tp] + 1,q.push(v);
        }
        return (depth[t] != -1);
    }
    inline int dfs(int x,int t,int _flow)
    {
        if(x == t) return _flow; int v,flow_ = 0;
        for(reg e = fire[x];e;e = edge[e]._nxt)
        {
            fire[x] = e;
            if(depth[v = edge[e].v] == depth[x] + 1&&edge[e].w)
            {
                int flow = dfs(v,t,min(_flow,edge[e].w));
                _flow -= flow,flow_ += flow;
                edge[e].w -= flow,edge[e ^ 1].w += flow;
                if(!_flow) break;
            }
        }
        if(!flow_) depth[x] = -1;
        return flow_;
    }
    inline int Dinic(int s,int t)
    {
        int ans = 0;
        while(Bfs(s,t))
        {
            for(reg i = 1;i <= n;i++) fire[i] = _ori[i];
            ans += dfs(s,t,inf);
        }
        return ans;
    }
}
int main()
{
    cnt = 1;
    n = Read(1),m = Read(1),s = Read(1),t = Read(1);
    for(reg i = 1;i <= m;i++)
    {
        int u = Read(1),v = Read(1),w = Read(1);
        add(u,v,w);
    }
    int ans = Dinitz::Dinic(s,t);
    printf("%d",ans);
    return 0;
}

例题P1343 地震逃生

#include <set>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define reg register int
#define isdigit(x) ('0' <= x&&x <= '9')
template<typename T>
inline T Read(T Type)
{
    T x = 0,f = 1;
    char a = getchar();
    while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    return x * f;
}
const int MAXN = 220,MAXM = 2010;
int cnt,n,m,s,t,_ori[MAXN];
typedef long long ll;
struct EDGE
{
    int v,_nxt;ll w;
    EDGE() {v = w = _nxt = 0;}
}edge[MAXM << 2];
inline void addedge(int u,int v,ll w)
{
    edge[++cnt]._nxt = _ori[u];
    edge[cnt].v = v;
    edge[cnt].w = w;    
    _ori[u] = cnt;
}
inline void add(int u,int v,ll w) {addedge(u,v,w),addedge(v,u,0ll);}
namespace EdmondKarp
{
    const int inf = 0x7f7f7f7f;
    struct Path {int v,e;}pre[MAXN];
    bool vis[MAXN];
    inline bool Bfs(int s,int t)
    {
        memset(vis,0,sizeof(vis));
        memset(pre,0,sizeof(pre));
        queue<int> q;
        q.push(s),vis[s] = 1;
        while(!q.empty())
        {
            int v,tp = q.front();q.pop();
            if(tp == t) return true;
            for(reg e = _ori[tp];e;e = edge[e]._nxt)
                if(!vis[v = edge[e].v]&&edge[e].w)
                {
                    pre[v].v = tp,pre[v].e = e;
                    if(v == t) return true;
                    vis[v] = 1,q.push(v);
                }
        }
        return false;
    }
    inline ll EK(int s,int t)
    {
        ll ans = 0;
        while(Bfs(s,t))
        {
            ll flow_ = inf;
            for(reg i = t;i != s;flow_ = min(flow_,edge[pre[i].e].w),i = pre[i].v);
            for(reg i = t;i != s;edge[pre[i].e].w -= flow_,edge[pre[i].e ^ 1].w += flow_,i = pre[i].v);
            ans += flow_;
        }
        return ans;
    }
}
int main()
{
    cnt = 1;
    ll stu;
    n = Read(1),m = Read(1),stu = Read(1ll);
    for(reg i = 1;i <= m;i++)
    {
        int u = Read(1),v = Read(1),w = Read(1);
        add(u,v,w);
    }
    ll ans = EdmondKarp::EK(1,n);
    if(ans == 0) printf("Orz Ni Jinan Saint Cow!");
    else printf("%lld %lld",ans,(stu / ans + (stu % ans?1:0)));
    return 0;
}

P1345 [USACO5.4]奶牛的电信Telecowmunication

#include <set>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define reg register int
#define isdigit(x) ('0' <= x&&x <= '9')
template<typename T>
inline T Read(T Type)
{
    T x = 0,f = 1;
    char a = getchar();
    while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    return x * f;
}
const int MAXN = 220,MAXM = 2010;
int cnt,n,m,s,t,_ori[MAXN];
typedef long long ll;
struct EDGE
{
    int v,_nxt;ll w;
    EDGE() {v = w = _nxt = 0;}
}edge[MAXM << 2];
inline void addedge(int u,int v,ll w)
{
    edge[++cnt]._nxt = _ori[u];
    edge[cnt].v = v;
    edge[cnt].w = w;    
    _ori[u] = cnt;
}
inline void add(int u,int v,ll w) {addedge(u,v,w),addedge(v,u,0ll);}
const int inf = 0x7f7f7f7f;
namespace EdmondKarp
{
    struct Path {int v,e;}pre[MAXN];
    bool vis[MAXN];
    inline bool Bfs(int s,int t)
    {
        memset(vis,0,sizeof(vis));
        memset(pre,0,sizeof(pre));
        queue<int> q;
        q.push(s),vis[s] = 1;
        while(!q.empty())
        {
            int v,tp = q.front();q.pop();
            if(tp == t) return true;
            for(reg e = _ori[tp];e;e = edge[e]._nxt)
                if(!vis[v = edge[e].v]&&edge[e].w)
                {
                    pre[v].v = tp,pre[v].e = e;
                    if(v == t) return true;
                    vis[v] = 1,q.push(v);
                }
        }
        return false;
    }
    inline ll EK(int s,int t)
    {
        ll ans = 0;
        while(Bfs(s,t))
        {
            ll flow_ = inf;
            for(reg i = t;i != s;flow_ = min(flow_,edge[pre[i].e].w),i = pre[i].v);
            for(reg i = t;i != s;edge[pre[i].e].w -= flow_,edge[pre[i].e ^ 1].w += flow_,i = pre[i].v);
            ans += flow_;
        }
        return ans;
    }
}
int main()
{
    cnt = 1;
    n = Read(1),m = Read(1),s = Read(1),t = Read(1);
    for(reg i = 1;i <= n;i++)
        if(i == s||i == t) add(i,n + i,inf);
        else add(i,n + i,1);
    for(reg i = 1;i <= m;i++)
    {
        int u = Read(1),v = Read(1);
        add(u + n,v,inf),add(v + n,u,inf);
    }
    ll ans = EdmondKarp::EK(s,t);
    printf("%d",ans);
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!