您的位置:首页 > Web前端 > React

zoj 2314 Reactor Cooling

2013-04-23 19:42 357 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314

大牛就是大牛 人家能想到咱就是想不到呀

根据所给流量下限(下限必流)

记录每个点的入度(in) 和出度(out) 然后用(上限-下限)进行建图 (这是还可以增加的流)

然后虚拟起点和汇点 根据每个点的 in 和 out

如果 in > out 说明此点需要流出(in - out ) 然后从起点连一条边 流为( in - out ) 等于给此点一个流出的机会

如果 in < out 说明此点需要流入 (out - in ) 然后向终点连一条边 流为 ( out - in ) 等于给此点一个流入的机会

然后求最大流 看是否最大流为满流(既等于初始化时从起点需要流出的量 且等于初始化时需要向汇点流入的量)

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define ll long long

using namespace std;
const int INF=0x3f3f3f3f;
const int MOD=100000007;
const int N=205;
const int M=100005;
int head
,I;
struct node
{
int j,next;
int k;
int flow;
}edge[M];
struct node1
{
int l,r,low,high;
}p[M];
int in
,out
;
int L
;
int st,nd;
void add(int i,int j,int flow,int k)
{
edge[I].j=j;
edge[I].k=k;
edge[I].flow=flow;
edge[I].next=head[i];
head[i]=I++;
}
bool bfs(int x1,int x2)
{
memset(L,-1,sizeof(L));
queue<int>qt;
qt.push(x1);
L[x1]=0;
while(!qt.empty())
{
int x=qt.front();
qt.pop();
for(int t=head[x];t!=-1;t=edge[t].next)
{
int j=edge[t].j;
if(edge[t^1].flow>0&&L[j]==-1)
{
L[j]=L[x]+1;
qt.push(j);
}
}
}
if(L[x2]==-1)
return false;
return true;
}
int dfs(int x,int sum)
{
if(x==nd)
return sum;
int tmp=sum;
for(int t=head[x];t!=-1;t=edge[t].next)
{
int j=edge[t].j;
if(edge[t].flow>0&&L[x]==L[j]+1)
{
int w=dfs(j,min(tmp,edge[t].flow));
edge[t].flow-=w;int k=edge[t].k;if(k!=-1)p[k].low+=w;
edge[t^1].flow+=w;k=edge[t^1].k;if(k!=-1)p[k].low-=w;
tmp-=w;
if(tmp==0)
break;
}
}
return (sum-tmp);
}
void init(int n,int m,int st,int nd,int &S,int &E)
{
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(int i=0;i<m;++i)
{
cin>>p[i].l>>p[i].r>>p[i].low>>p[i].high;
out[p[i].l]+=p[i].low;
in[p[i].r]+=p[i].low;
add(p[i].l,p[i].r,p[i].high-p[i].low,i);
add(p[i].r,p[i].l,0,-1);
}
for(int i=1;i<=n;++i)
{
if(in[i]>out[i])
{
add(st,i,in[i]-out[i],-1);
add(i,st,0,-1);
S+=(in[i]-out[i]);
}
if(in[i]<out[i])
{
add(i,nd,out[i]-in[i],-1);
add(nd,i,0,-1);
E+=(out[i]-in[i]);
}
}
}
int main()
{
//freopen("data.in","r",stdin);
int T;
cin>>T;
while(T--)
{
int n,m;
while(cin>>n>>m)//cout<<n<<m<<endl;
{
memset(head,-1,sizeof(head));
I=0;
st=0;
nd=n+1;
int S=0,E=0;
init(n,m,st,nd,S,E);//cout<<S<<" "<<E<<endl;
int ans=0;
while(bfs(nd,st))
{
int k;
while((k=dfs(st,INF)))
ans+=k;
}
//cout<<ans<<" "<<S<<" "<<E<<endl;
if(S==ans&&E==ans)
{
cout<<"YES"<<endl;
for(int i=0;i<m;++i)
cout<<p[i].low<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: