P4553 80人環遊世界 上下界可行費用流

2021-10-22 17:07:51 字數 2174 閱讀 5021

link

無特殊說明費用都是0

新建源點s

ss和匯點t

tt,新建虛擬限制節點xun

ixuni

xuni s

ss連向xun

ixuni

xuni

流量[ 0,

m]

[0,m]

[0,m

]的邊,表示可以派出的人不能超過mmm

x un

ixuni

xuni

連向每個點流量[0,

inf]

[0,inf]

[0,inf

]的邊,表示可以派出任何人去這個點

對於邊(x,

y,w)

(x,y,w)

(x,y,w

),讓x+n

x+nx+

n連向y

yy流量[0,

inf]

[0,inf]

[0,inf

]費用w

ww的邊,表示邊之間的轉移

對於每個點x

xx,讓x

xx連向x+n

x+nx+

n流量[vx

,vx]

[v_x,v_x]

[vx​,v

x​]的邊,表示必須經過v

xv_x

vx​次

對於每個點連向t

tt流量為[0,

inf]

[0,inf]

[0,inf

],表示可以在任何點結束

然後t

tt連向s

ss流量為[0,

inf]

[0,inf]

[0,inf

]的邊,也就是讓s,t

s,ts,

t滿足流量守恆

新建s sss

ss和t ttt

tt,補齊圖中每個點的流量

如此一來,就是一張有源匯的網路圖,可以跑最大流找出可行流

但這裡是需要最小化費用,那麼從ssss

ss向t ttt

tt跑最小費用最大流即可

#include

using

namespace std;

const

int inf =

1e9;

const

int maxn =

3e5+10;

int v[maxn]

,in[maxn]

,out[maxn]

;int n,m,s,t,xuni,ss,tt,ans;

struct edged[maxn]

;int head[maxn]

,cnt=1;

void

add(

int u,

int v,

int l,

int r,

int w)

,head[u]

= cnt;

d[++cnt]

=( edge )

,head[v]

= cnt;

}int flow[maxn]

,dis[maxn]

,pre[maxn]

,vis[maxn]

,ned;

bool

spfa

(int s,

int t)}}

return dis[t]

!=inf;

}int

dinic

(int s,

int t)}if

( ned!=0)

//沒有滿流,說明不存在可行流

return ans;

}void

build()

for(

int i=

1;i<=n;i++

)for

(int j=i+

1;j<=n;j++

)for

(int i=

1;i<=t;i++

)add

(t,s,

0,inf,0)

;//使得源點和匯點滿足流量守恆

}int

main()

洛谷P4553 80人環遊世界

題意 有m個人,給定n個城市構成dag。每個城市恰好有vi個人經過,每條邊有費用。每個人自選起點,終點。求最小費用。解 首先拆點,連邊,流量為 vi,vi 然後做有上下界有源匯最小費用可行流即可。1 include 2 include 3 include 4 include 5 include 6 ...

BZOJ2055 80人環遊世界

題解 總算a掉了,各種蛋疼。int main for1 i,n for2 j,i 1,n for1 i,n insert i n,t,0,inf,0 insert t,s,0,inf,0 mcf printf d n mincost return0 s是附加源,sss是真正的源,t是真正的匯。這樣構...

bzoj 2055 80人環遊世界

有源匯上下界最小費用可行流。將每個國家拆點。源點向乙個新建節點連一條上界為總人數下界為0費用為0的邊。新建節點向每個國家的入點連一條上界為正無窮下界為0費用為0的邊。每個國家的入點向出點連一條上下界均為該國家訪問人數費用為0的邊。每個國家的出點向匯點連一條上界為正無窮下界為0費用為0的邊。對於國家i...