题意:

给点数n和边数m。

接下来m条有向边。

a b c d 一次代表起点终点,下界上界。

求:

判断是否存在可行流,若存在则输出某可行流。否则输出IMPOSSIBLE

思路:

《一种简易的方法求解流量有上下界的网络中的网络流问题》

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string.h>
#include<vector>
#define MAXN 4050
#define MAXM 40050
using namespace std;
const int inf=0x3f3f3f3f;
vector<pair<pair<int,int>,pair<int,int> > >jilu;
int inme[],outme[];
struct Edge
{
int v,c,f,nx;
Edge() {}
Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
} E[MAXM];
int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],sz;
void init()
{
sz=;
memset(G,-,sizeof(G));
}
void add_edge(int u,int v,int c)
{
E[sz]=Edge(v,c,,G[u]);
G[u]=sz++;
E[sz]=Edge(u,,,G[v]);
G[v]=sz++;
}
bool bfs(int S,int T)
{
static int Q[MAXN];
memset(dis,-,sizeof(dis));
dis[S]=;
Q[]=S;
for (int h=,t=,u,v,it; h<t; ++h)
{
for (u=Q[h],it=G[u]; ~it; it=E[it].nx)
{
if (dis[v=E[it].v]==-&&E[it].c>E[it].f)
{
dis[v]=dis[u]+;
Q[t++]=v;
}
}
}
return dis[T]!=-;
}
int dfs(int u,int T,int low)
{
if (u==T) return low;
int ret=,tmp,v;
for (int &it=cur[u]; ~it&&ret<low; it=E[it].nx)
{
if (dis[v=E[it].v]==dis[u]+&&E[it].c>E[it].f)
{
if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
{
ret+=tmp;
E[it].f+=tmp;
E[it^].f-=tmp;
}
}
}
if (!ret) dis[u]=-;
return ret;
}
int dinic(int S,int T)
{
int maxflow=,tmp;
while (bfs(S,T))
{
memcpy(cur,G,sizeof(G));
while (tmp=dfs(S,T,inf)) maxflow+=tmp;
}
return maxflow;
}
int main(){
init();
int n,m;
scanf("%d%d",&n,&m);
int a,b,c,d;
for(int i=;i<=m;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
add_edge(a,b,d-c);
outme[a]+=c;
inme[b]+=c;
jilu.push_back(make_pair(make_pair(a,b),make_pair(c,d)));
}
for(int i=;i<=n;i++){
if(inme[i]-outme[i]>=){
add_edge(,i,inme[i]-outme[i]);
}
else{
add_edge(i,n+,outme[i]-inme[i]);
}
}
dinic(,n+);
memcpy(cur,G,sizeof(G));
int v;
for(int i=;i<=n;i++){
if(inme[i]-outme[i]>=){
for (int it=cur[]; ~it; it=E[it].nx){
v=E[it].v;
if(v==i){
if(E[it].f!=E[it].c){
puts("NO");
return ;
}
break;
}
}
}
else{
for(int it=cur[i];~it;it=E[it].nx){
v=E[it].v;
if(v==n+){
if(E[it].f!=E[it].c){
puts("NO");
return ;
}
break;
}
}
}
}
puts("YES");
for(int i=;i<jilu.size();i++){
a=jilu[i].first.first;
b=jilu[i].first.second;
c=jilu[i].second.first;
for(int it=cur[a];~it;it=E[it].nx){
v=E[it].v;
if(v==b){
printf("%d\n",E[it].f+c);
break;
}
}
}
}
05-04 05:39