zoj 2314 Reactor Cooling

 

 

好郁闷。最大流。但是没见过这种类型的,想了种方法,但是答案不对 = =。。。

 

搜了下,这个是另一种类型,无源汇(其实我觉得汇源比较顺口。。)的有上下界的最大流。

 

引用http://blog.imzzl.com/2010/07/630.html的一段话

 

 


总的来说就是新建一个原点汇点 s,t,对原来的每个点i,设m(i)=sum{b}-sum{b}其中b<>为流量下界,若m(i)>0,连一条容量为m(i)的边;若m(i)<0,连一条容量为|m(i)|的边。然后将原来边的容量变为c-b。求一次最大流。如果与s和t关联的边全部满流,则可行流存在,且每条边的流量为现在的流量+流量的下界。否则不存在可行流。

 


 

 

下了个《一种简易的方法求解流量有上下界的网络中网络流问题》明天印出来看看。。

 

#include #include #include #include #include #include #define MAX 210 using namespace std; int n,m; int cap[MAX][MAX]; int flow[MAX][MAX]; int EKarp(int s,int t) { int a[MAX],u,v,f,pre[MAX]; f = 0; queue Q; memset(flow,0,sizeof(flow)); while(1) { Q.push(s); memset(a,0,sizeof(a)); a[s] = INT_MAX; while( !Q.empty() ) { u = Q.front(); Q.pop(); for(v=1; v<=n+1; v++) if( !a[v] && cap[u][v] > flow[u][v] ) { Q.push(v); a[v] = a[u] < cap[u][v] - flow[u][v] ? a[u] : cap[u][v] - flow[u][v]; pre[v] = u; } } if( a[t] == 0 ) break; for(u=t; u!=s; u=pre[u]) { flow[pre[u]][u] += a[t]; flow[u][pre[u]] -= a[t]; } f += a[t]; } return f; } int f[MAX*MAX],t[MAX*MAX]; int l[MAX*MAX]; int main() { int i,k,c,ncases; scanf("%d",&ncases); while( ncases-- ) { scanf("%d%d",&n,&m); memset(cap,0,sizeof(cap)); for(i=1; i<=m; i++) { scanf("%d%d%d%d",&f[i],&t[i],&l[i],&c); cap[f[i]][t[i]] = c - l[i]; cap[0][t[i]] += l[i]; cap[f[i]][n+1] += l[i]; } EKarp(0,n+1); int flag = 1; for(i=1; i<=m; i++) if( cap[0][t[i]] - flow[0][t[i]] != 0 || cap[f[i]][n+1] - flow[f[i]][n+1] != 0 ) { flag = 0; break; } if( flag ) { printf("YES/n"); for(i=1; i<=m; i++) printf("%d/n",flow[f[i]][t[i]]+l[i]); } else printf("NO/n"); } return 0; }

 

你可能感兴趣的:(网络流,二分图匹配,zoj)