ZOJ 2314 上下界最大流

来源:互联网 发布:朗威数字化实验室 淘宝 编辑:程序博客网 时间:2024/06/05 10:12

增加源和汇,所有边按照上界-下界作为上界,无下界建图,然后所有点的流入和流出统计,点流入的与源连上容量为流入量的边,流出的连上汇就行,做一次最大流,如果所有连接源点的边都满流就是有解,否则无解,解即当前边的流量加上原来的下界

错误n次~ 坑爹啊 以后要小心 注意未知数组尽量开到最大 本以为n为200 开10000不会有问题 结果100000才过。。。。


#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#include<queue>#include<memory.h>using namespace std;const int maxn=1007,maxm=100007,inf=1<<30;vector<int> next[maxn];int b[maxn][maxn],flow[maxn][maxn];int x[maxm],y[maxm];int out[maxn];int d[maxn];bool bfs(int s,int t){memset(d,0,sizeof(d));d[s]=1;queue<int> q;q.push(s);int i,u,v;while(!q.empty()){u=q.front();q.pop();for(i=0;i<next[u].size();i++){v=next[u][i];if(flow[u][v]>0 && d[v]==0){d[v]=d[u]+1;if(v == t){return true;}q.push(v);}}}return false;}int dfs(int u,int t,int limit){if(u == t){return limit;}int i,v,cost=0;for(i=0;i<next[u].size();i++){v=next[u][i];if(flow[u][v]>0 && d[v]==d[u]+1){int tmp = dfs(v,t,min(limit-cost,flow[u][v]));if(tmp>0){flow[u][v] -= tmp;flow[v][u] += tmp;cost += tmp;if(cost == limit){break;}}else{d[v] = -1;}}}return cost;}int Dinic(int s,int t){int ret=0;while(bfs(s,t)){ret += dfs(s,t,inf);}return ret;}int main(){int T;scanf("%d",&T);while(T--){int i,n,m,u,v,l,c,s,t;scanf("%d%d",&n,&m);s=0,t=n+1;memset(out,0,sizeof(out));memset(flow,0,sizeof(flow));memset(b,0,sizeof(b));for(i=0;i<=t;i++){next[i].clear();}for(i=0;i<m;i++){scanf("%d%d%d%d",&u,&v,&l,&c);next[u].push_back(v);next[v].push_back(u);out[u] -= l;out[v] += l;flow[u][v]=c-l;b[u][v]=l;x[i]=u;y[i]=v;}int sum=0;for(i=1;i<=n;i++){if(out[i]>0){next[s].push_back(i);next[i].push_back(s);flow[s][i]=out[i];sum += out[i];}else if(out[i]<0){next[i].push_back(t);next[t].push_back(i);flow[i][t] = -out[i];}}if(Dinic(s,t) == sum){puts("YES");for(i=0;i<m;i++){u=x[i],v=y[i];printf("%d\n",flow[v][u]+b[u][v]);}}else{puts("NO");}puts("");}return 0;}


原创粉丝点击