有上下界的網路流

2021-09-12 03:10:25 字數 4616 閱讀 7356

傳送門115

傳送門116

傳送門117

loj115 無源匯有上下界可行流

題解:一時半會不想寫題於是打算搞事情 | 誰說我這是正兒八經給別人看了

明明學這玩意過去這麼久了怎麼現在才開始把板子放上來啊

很容易想到可以把每條邊的容量變成up-low。但是因為這之後流量不守恆,再搞乙個超級源點s和超級匯點t,然後記錄一下每個點的val[i]=in[i](入流下界之和)-out[i](出流下界之和)。

當val[i]>0,s到i連邊,容量val[i];當val[i]<0,i到t連邊,容量-val[i]。

然後對s,t求最大流。當從s出去的邊全部滿流時有解。

**:

#include

#include

#include

#define maxn 205

#define maxm 50005

#define inf 0x3f3f3f3f

using

namespace std;

int n,m,s,t,val[maxn]

,flow,dist[maxn]

,cur[maxn]

,head[maxn]

,ncnt,ans[maxm]

,l[maxm]

;struct node e[maxm]

;void

addedge

(int u,

int v,

int i,

int cap)

void

add(

int u,

int v,

int i,

int w)

bool

bfs()}

return dist[t]

>=0;

}int

dfs(

int u,

int cap)

}return flow;

}void

dinic()

intmain()

s=0,t=n+1;

for(

int i=

1;i<=n;i++)if

(val[i]

>0)

add(s,i,

0,val[i]);

else

if(val[i]

<0)

add(i,t,0,

-val[i]);

dinic()

;for

(int p=head[s]

;p;p=e[p]

.nxt)

if(e[p]

.cap)

for(

int i=

2;i<=ncnt;i++

) ans[e[i]

.i]=e[i^1]

.cap;

printf

("yes\n");

for(

int i=

1;i<=m;i++

)printf

("%d\n"

,ans[i]

+l[i]);

}

loj116 有源匯有上下界最大流

題解:語死早表示這玩意怎麼可能是別人能看的

我們先跑一發可行流。

可以從t到s連一條容量inf的邊,轉化成無源匯有上下界最大流,那麼跑完之後s到t的權值即為所求。

然後在殘量網路上跑s-t最大流即可。

所求為二者之和。

**:

#include

#include

#include

#define maxn 205

#define maxm 50005

#define inf 0x3f3f3f3f

using

namespace std;

int n,m,s,t,val[maxn]

,flow,dist[maxn]

,cur[maxn]

,head[maxn]

,ncnt,ans[maxm]

,l[maxm]

,s0,t0;

struct node e[maxm]

;void

addedge

(int u,

int v,

int cap)

void

add(

int u,

int v,

int w)

bool

bfs()}

return dist[t]

>=0;

}int

dfs(

int u,

int cap)

}return flow;

}void

dinic()

intmain()

s=0,t=n+1;

for(

int i=

1;i<=n;i++)if

(val[i]

>0)

add(s,i,val[i]);

else

if(val[i]

<0)

add(i,t,

-val[i]);

add(t0,s0,inf)

;dinic()

;for

(int p=head[s]

;p;p=e[p]

.nxt)

if(e[p]

.cap)

for(

int i=

1;i<=n;i++

)for

(int p=head[i]

;p;p=e[p]

.nxt)

if(e[p]

.v==t||e[p]

.v==s) e[p]

.cap=e[p^1]

.cap=0;

for(

int p=head[s0]

;p;p=e[p]

.nxt)

if(e[p]

.v==t0)

s=s0,t=t0;

dinic()

;printf

("%d\n"

,flow)

;}

loj117 有源匯有上下界最小流

題解:求完可行流後跑t-s最大流,二者相減即為所求。

**:

#include

#include

#include

#define maxn 50010

#define maxm 500005

#define ll long long

#define inf (ll)1e16

using

namespace std;

int n,m,s,t,val[maxn]

,dist[maxn]

,cur[maxn]

,head[maxn]

,ncnt,ans[maxm]

,l[maxm]

,s0,t0;

ll flow;

struct node e[maxm]

;void

addedge

(int u,

int v,ll cap)

void

add(

int u,

int v,ll w)

bool

bfs()}

return dist[t]

>=0;

}ll dfs

(int u,ll cap)

}return flow;

}void

dinic()

intmain()

s=0,t=n+1;

for(

int i=

1;i<=n;i++)if

(val[i]

>0)

add(s,i,val[i]);

else

if(val[i]

<0)

add(i,t,

-val[i]);

add(t0,s0,inf)

;dinic()

;for

(int p=head[s]

;p;p=e[p]

.nxt)

if(e[p]

.cap)

for(

int i=

1;i<=n;i++

)for

(int p=head[i]

;p;p=e[p]

.nxt)

if(e[p]

.v==t||e[p]

.v==s) e[p]

.cap=e[p^1]

.cap=0;

for(

int p=head[s0]

;p;p=e[p]

.nxt)

if(e[p]

.v==t0) flow=e[p]

.cap,e[p]

.cap=e[p^1]

.cap=0;

s=t0,t=s0;

dinic()

;printf

("%lld\n"

,flow)

;}

有上下界網路流

前言 下面寫得只是一些十分基礎的東西,是給我以後自己看的,想要徹底弄明白這個內容,推薦去看liu runda。注 為了方便,下面所有的 x,y,l,r 都表示一條從x連向y,流量下界為l,流量上界為r的邊。問題簡述 給出乙個有向圖,每條邊有流量上下界,沒有源點和匯點,要求找到一種流的方法,使得每個點...

有上下界的網路流

有上下界的網路流 這幾天看了周源的 一種簡易的方法求解流量有上下界的網路中網路流問題 並完成了 sgu 194 zoj 2314 reactor cooling,sgu 176 flow construction 和hoj 2135 poj 2396 budget三道題。作為周源文章中提到的求解上下...

有上下界的網路流

1.無匯源有上下界最大流 以前寫的最大流預設的下界為0,而這裡的下界卻不為0,所以我們要進行再構造讓每條邊的下界為0,這樣做是為了方便處理。對於每根管子有乙個上界容量up和乙個下界容量low,我們讓這根管子的容量下界變為0,上界為up low。可是這樣做了的話流量就不守恆了,為了再次滿足流量守恆,即...