bzoj 2055 80人環遊世界

2022-05-20 06:53:20 字數 1475 閱讀 5470

有源匯上下界最小費用可行流。

將每個國家拆點。

源點向乙個新建節點連一條上界為總人數下界為0費用為0的邊。

新建節點向每個國家的入點連一條上界為正無窮下界為0費用為0的邊。

每個國家的入點向出點連一條上下界均為該國家訪問人數費用為0的邊。

每個國家的出點向匯點連一條上界為正無窮下界為0費用為0的邊。

對於國家i能到國家j,i的出點向j的入點連一條上界為正無窮下界為0費用為機票費的邊。

然後對圖求一邊有源匯上下界最小費用可行流即可得出最小費用。

具體做法是先將所有邊的下界乘費用相加,這一部分是必須的費用,然後按照「有源匯上下界可行流」建圖,從超級源向超級匯跑一遍最小費用最大流,兩個費用相加即為答案。

至於本題本身的建圖思路,與bzoj1927星際競速類似,下面放乙份十分良心的題解。

天地良心無與倫比誰與爭鋒的一篇題解

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;

7const

int dian=305;8

const

int bian=100005;9

const

int inf=0x3f3f3f3f;10

inth[dian],nxt[bian],ver[bian],val[bian],cos[bian];

11int

d[dian],v[dian],with[dian],minn[dian];

12int

in[dian],out

[dian];

13int

n,m,tot,aa,mf;

14int

s,t,ss,tt;

15void add(int a,int b,int c,int d,int

e)21

bool

tell()44}

45}46}

47if(d[t]==0x3f3f3f3f)48

return

false;49

return

true;50

}51intzeng()

56return minn[t]*d[t];57}

58int

dinic_cost()

64int

main()

81for(int i=1;i)

82for(int j=1;j<=n-i;j++)

87 add(tt,ss,0,inf,0

);88

for(int i=1;i<=tt;i++)

94 printf("

%d",mf+dinic_cost());

95return0;

96 }

注意題意敘述不清,每個人可以從任意乙個國家開始走。

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是真正的匯。這樣構...

BZOJ2055 80人環遊世界

上下界最小費用流 限制點訪問量 拆點 i,i 建圖 1.s s m,m 0 2.s i 0,inf 0 i t 0,inf 0 3.i j 0,inf x 4.i i vi,vi 0 然後就是上下界流的常見套路啦 根據 調整 原則 先是每個點點權為di ini outi 然後 0的連源點 0的連匯點...

bzoj2055 80人環遊世界(可行流)

傳送門 表示完全看不懂最小費用可行流 據某大佬說 我們考慮拆點,然後進行如下連邊 s 向 a i 連邊,權值 0 容量 0,m a i 向 a i 連邊,權值 0 容量 v i,v i 如果存在邊 i,j 則連邊 a i a i 權值為 w 容量 0,m a i 向 t 連邊,權值 0 容量 0,m...