最大流问题——无源汇有上下界最大流 sgu194 Reactor Cooling

来源:互联网 发布:powershell 登陆linux 编辑:程序博客网 时间:2024/06/05 18:57

关于最大流问题,看到了一篇大神写的非常好的博客:点击打开链接

这里面讲的都非常详细了,所以就不多说了,贴代码主要是因为习惯了自己的代码风格……

#include <iostream>#include <cstdio>#include <cstdlib>#include <set>#include <cstring>#include <vector>#include <map>#include <algorithm>#include <cmath>#include <queue>using namespace std;const int maxn = 10000+10;const int MAXM = 1000000+10;const int INF = 0x3f3f3f3f;int n;struct Edge {    int v,flow,id,link;} edge[MAXM];int head[maxn],tol;int dis[maxn],du[maxn],dn[MAXM],ans[MAXM];bool vis[maxn];void add(int u,int v,int flow,int id) {    edge[tol].v = v,edge[tol].flow = flow,edge[tol].id = id,edge[tol].link = head[u],head[u] = tol++;    edge[tol].v = u,edge[tol].flow = 0,edge[tol].id = 0,edge[tol].link = head[v],head[v] = tol++;}bool bfs(int s,int t) {    memset(dis,0,sizeof(dis));    dis[s] = 1;    queue<int>q;    q.push(s);    while(!q.empty()) {        int u = q.front();        q.pop();        if(u == t)return true;        for(int i = head[u]; ~i; i = edge[i].link) {            int v = edge[i].v;            if(!dis[v] && edge[i].flow) {                dis[v] = dis[u] + 1;                q.push(v);            }        }    }    return false;}int dfs(int s,int t,int maxf) {    if(s == t)return maxf;    int ret = 0;    for(int i = head[s]; ~i; i = edge[i].link) {        int v = edge[i].v,flow = edge[i].flow;        if(dis[s] + 1 == dis[v] && edge[i].flow) {            int Min = min(maxf-ret,edge[i].flow);            flow = dfs(v,t,Min);            edge[i].flow -= flow;            edge[i^1].flow += flow;            ret += flow;            if(ret == maxf)return ret;        }    }    return ret;}int Dinic(int s,int t) {    int ans = 0;    while(bfs(s,t))ans += dfs(s,t,INF);    return ans;}int main() {#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif  ONLINE_JUDGE    int u,v,low,up,m;    while(~scanf("%d%d",&n,&m)) {        memset(head,-1,sizeof(head));        memset(dn,0,sizeof(dn));        memset(du,0,sizeof(du));        memset(ans,0,sizeof(ans));        tol = 0;        for(int i = 1; i <= m; i++) {            scanf("%d%d%d%d",&u,&v,&low,&up);            add(u,v,up-low,i);            du[u] -= low;            du[v] += low;            dn[i] = low;        }        int cnt = tol;        for(int i = 1; i <= n; i++) {            if(du[i] > 0)add(0,i,du[i],0);            if(du[i] < 0)add(i,n+1,-du[i],0);        }        int sum = Dinic(0,n+1);        bool flag = true;        for(int i = head[0]; i != -1; i = edge[i].link) {            if(edge[i].flow  > 0) {                flag = false;                break;            }        }        if(!flag)puts("NO");        else {            puts("YES");            for(int i = 0; i < cnt; i++)ans[edge[i].id] = edge[i^1].flow;            for(int i = 1; i <= m; i++)                printf("%d\n",ans[i] + dn[i]);        }    }    return 0;}


0 0
原创粉丝点击