最大流问题——有源汇有上下界的最小流sgu176 Flow construction

来源:互联网 发布:ipad钢琴软件 编辑:程序博客网 时间:2024/06/14 15:23

对于这个题,,我只想知道为什么数组开大一点点(没有达到MLE的程度)返回的结果是PE??很搞不懂……貌似题目中说了N的范围,,但是M的范围好像没说?(也许眼瞎了……)

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

在链接中说到“c等于0表示加工没有上界限制,下界为0”,,但我对题目的理解是:c==0时,表示上界为Zi,下界为0……

#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 = 100+10;const int MAXM = 11111;  // 就是这了……如果开1e5就不行了const int INF = 0x3f3f3f3f;int n,node,st,et;struct Edge {    int v,flow,id,link;} edge[MAXM];int dn[MAXM];int head[maxn],tol;int dis[maxn],du[maxn],ans[MAXM];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,c,m,low,up;    while(~scanf("%d%d",&n,&m)) {        memset(head,-1,sizeof(head));        memset(dn,0,sizeof(dn));        memset(du,0,sizeof(du));        memset(edge,0,sizeof(edge));        tol = 0;        for(int i = 1; i <= m; i++) {            scanf("%d%d%d%d",&u,&v,&up,&c);            if(c)du[u] -= up,du[v] += up,dn[i] = up;//把add(u,v,up-up,0)加上也没有意义            else add(u,v,up,i);        }        st = n+1,et = n+2;        for(int i = 1; i <= n; i++) {            if(du[i] > 0)add(st,i,du[i],0);            if(du[i] < 0)add(i,et,-du[i],0);        }        Dinic(st,et);        add(n,1,INF,0);        Dinic(st,et);        bool flag = true;        for(int i = head[st]; ~i; i = edge[i].link) {            if(edge[i].flow > 0) {                flag = false;                break;            }        }        if(!flag)printf("Impossible\n");        else {            int maxflow = 0,i = 0;            for(i = head[n]; ~i; i = edge[i].link)                if(edge[i].v == 1)break;            maxflow = edge[i^1].flow;            printf("%d\n",maxflow);            for(int i = 0; i < tol; i++)                ans[edge[i].id] = edge[i^1].flow;            for(int i = 1; i <= m; i++) {                if(i == 1)printf("%d",ans[i] + dn[i]);                else printf(" %d",ans[i] + dn[i]);            }            if(m) printf("\n");        }    }    return 0;}


0 0