Description
The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear reactor to produce plutonium for the nuclear bomb they are planning to create. Being the wicked computer genius of this group, you are responsible for developing the cooling system for the reactor.
The cooling system of the reactor consists of the number of pipes that special cooling liquid flows by. Pipes are connected at special points, called nodes, each pipe has the starting node and the end point. The liquid must flow by the pipe from its start point to its end point and not in the opposite direction.
Let the nodes be numbered from 1 to N . The cooling system must be designed so that the liquid is circulating by the pipes and the amount of the liquid coming to each node (in the unit of time) is equal to the amount of liquid leaving the node. That is, if we designate the amount of liquid going by the pipe from i-th node to j -th as fi,j, (put fi,j = 0 if there is no pipe from node i to node j ), for each i the following condition must hold:
Each pipe has some finite capacity, therefore for each i and j connected by the pipe must be fi,j ≤ ci,j where ci,j is the capacity of the pipe. To provide sufficient cooling, the amount of the liquid flowing by the pipe going from i-th to j -th nodes must be at least li,j , thus it must be fi,j ≥ li,j. Given ci,j and li,j for all pipes, find the amount fi,j, satisfying the conditions specified above
Input
Output
Sample Input
4 6 1 2 1 2 2 3 1 2 3 4 1 2 4 1 1 2 1 3 1 2 4 2 1 2 4 6 1 2 1 3 2 3 1 3 3 4 1 3 4 1 1 3 1 3 1 3 4 2 1 3
Sample Output
NO YES 1 2 3 2 1 1
rt,开始以为下界的处理要取相反数加进去,但是没法输出结果啊,何况也不对orz
正解:百度有上下界限制的网络流,发现这是一类问题,以”无源点汇点“这种最为基础和简单,推荐博文,简单的说就是利用对于每个点而言 入边下界+入边自由流==出边下界+出边自由流 ,既然给出下界,那么我用这个数给源点到这个点与这个点到汇点建边,既然限制下限必须达到,那么就是满流才输出yes,满流的判断十分简单。但是如何输出最终的可行流,回想flow数组的定义:(算法导论P418)额外流量=该边容量-该边流量 残存网络中: cf(u,v)=c(u,v)-f(u,v) ;如果该边流量等于该边容量 cf(u,v)=f(v,u) 。那么既然是满流,flow应该是反向边的流量,最终答案就是flow[i^1]+low[i]
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=1000000;
const int mn=505*505*3;
const int oo=1000000000;
int node,src,dest,edge;
int reach[mm],flow[mm],nxt[mm];
int head[mn],work[mn],dis[mn],q[mn];
inline int min(int a,int b)
{
return a<b?a:b;
}
inline void prepare(int _node,int _src,int _dest)
{
node=_node,src=_src,dest=_dest;
for(int i=0;i<node;++i)head[i]=-1;
edge=0;
}
inline void addedge(int u,int v,int c1,int c2=0)
{
reach[edge]=v,flow[edge]=c1,nxt[edge]=head[u],head[u]=edge++;
reach[edge]=u,flow[edge]=c2,nxt[edge]=head[v],head[v]=edge++;
}
bool Dinic_bfs()
{
int i,u,v,l,r=0;
for(i=0;i<node;++i)dis[i]=-1;
dis[q[r++]=src]=0;
for(l=0;l<r;++l)
for(i=head[u=q[l]];i>=0;i=nxt[i])
if(flow[i]&&dis[v=reach[i]]<0)
{
dis[q[r++]=v]=dis[u]+1;
if(v==dest)return 1;
}
return 0;
}
int Dinic_dfs(int u,int exp)
{
if(u==dest)return exp;
for(int &i=work[u],v,tmp;i>=0;i=nxt[i])
if(flow[i]&&dis[v=reach[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)
{
flow[i]-=tmp;
flow[i^1]+=tmp;
return tmp;
}dis[u]--;
return 0;
}
int Dinic_flow()
{
int i,ret=0,delta;
while(Dinic_bfs())
{
for(i=0;i<node;++i)work[i]=head[i];
while(delta=Dinic_dfs(src,oo))ret+=delta;
}
return ret;
}
int Edge[40000],Flow[40000];
int main()
{
// freopen("cin.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&n,&m))
{
prepare(n+2,0,n+1);
int sum=0;
for(int i=0;i<m;i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
sum+=c;
addedge(src,b,c);
addedge(a,dest,c);
Edge[i]=edge;
Flow[i]=c;
addedge(a,b,d-c);
}
if(sum!=Dinic_flow())
{
puts("NO");
continue;
}
else
{
puts("YES");
for(int i=0;i<m;i++){
printf("%d\n",flow[Edge[i]^1]+Flow[i]);
}
}
}
return 0;
}

本文探讨了在恐怖组织由知名国际恐怖分子Ben Bladen领导的核反应堆建设中,负责设计冷却系统的难题。通过引入节点和管道的概念,文章详细阐述了如何确保液体在系统中循环流动,并满足特定的流量条件。提出了利用网络流理论中的“无源点汇点”模型,为冷却系统设计提供了一种有效的方法。进一步解释了如何通过调整流量,确保液体在每个节点的流入量等于流出量,从而实现系统平衡。最后,文章提供了具体的算法步骤和实例分析,展示了如何通过输入参数计算出满足条件的流量分配,以及如何在实际应用中输出可行的解决方案。

971

被折叠的 条评论
为什么被折叠?



