洛谷P4013 數字梯形問題(費用流)

2022-03-01 14:18:03 字數 1872 閱讀 3655

傳送門

兩個感受:碼量感人……大佬nb……

規則一:$m$條路徑都不相交,那麼每乙個點只能經過一次,那麼考慮拆點,把每乙個點拆成$a_$和$b_$,然後兩點之間連一條容量$1$,費用該點本身數值的邊,表明這個點只能被選一次,然後每乙個點的$b$向它能到達的點的$a$連邊,表明能從這個點到另乙個點,容量隨意,費用$0$,然後源點向第一排所有點的$a$連邊,最後一排所有點的$b$向匯點連邊,都是容量隨意,費用$0$,然後跑乙個最大費用流即可

規則二:每乙個點可以被選多次,那麼不用拆點了,直接每乙個點向它能到的點連邊,容量$1$,表明一條邊只能被選一次,費用為該點的數值,源點向第一排所有點連邊,容量$1$,費用$0$,最後一排所有點向匯點連邊,費用為該點的數值,然後跑乙個最大費用流即可

規則三:把每一條邊只能選一次的限制去掉,總之就是除了源點到第一排的邊,其他邊的容量都改為$inf$,然後跑乙個最大費用流

1

//minamoto

2 #include3

#define inf 0x3f3f3f3f

4using

namespace

std;

5#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?eof:*p1++)

6char buf[1

<<21],*p1=buf,*p2=buf;

7 inline int

read()

17const

int n=10005,m=50005;18

int ver[m],head[n],flow[m],edge[m],next[m],tot=1;19

int vis[n],dis[n],disf[n],pre[n],last[n],s=0,t=10000;20

int a[25][55],b[25][55

];21 queueq;

22 inline void add(int u,int v,int f,int

e)26

bool

spfa()38}

39}40return ~pre[t];41}

42int

dinic()52}

53return

maxcost;54}

55void

clear()

58int

main()

74for(int i=1;i<=k;++i)

78 printf("

%d\n

",dinic());

79clear();

80 k=m;

81for(int i=1;i<=k;++i)

82 add(s,b[1][i],1,0

);83

for(int i=1;ik)

84for(int j=1;j<=k;++j)

88for(int i=1;i<=k;++i)

89add(b[n][i],t,inf,a[n][i]);

90 printf("

%d\n

",dinic());

91clear();

92 k=m;

93for(int i=1;i<=m;++i) add(s,b[1][i],1,0

);94

for(int i=1;ik)

95for(int j=1;j<=k;++j)

99for(int i=1;i<=k;++i) add(b[n][i],t,inf,a[n][i]);

100 printf("

%d\n

",dinic());

101return0;

102 }

洛谷P4013數字梯形問題 網路流24題

題目 最大費用最大流裸題 注意 在第二種情況中,底層所有點連向匯點的邊容量應該為inf,因為可以有多條路徑結束在同乙個點。為這個調了半天.如下 include include include include using namespace std queue q intconst maxn 1605...

P4013 數字梯形問題 網路流

給定乙個由 nn 行數字組成的數字梯形如下圖所示。梯形的第一行有 mm 個數字。從梯形的頂部的 mm 個數字開始,在每個數字處可以沿左下或右下方向移動,形成一條從梯形的頂至底的路徑。分別遵守以下規則 從梯形的頂至底的 mm 條路徑互不相交 從梯形的頂至底的 mm 條路徑僅在數字結點處相交 從梯形的頂...

luogu P4013 數字梯形問題

三倍經驗,三個條件,分別對應了常見的3種模型,第一種是限制每個點只能一次且無交點,我們可以把這個點拆成乙個出點乙個入點,capacity為1,這樣就限制了只選擇一次,第二種是可以有交點,但不能有交邊,那我們就不需要拆點,限制每條capacity都為1就可以了,第三種直接連,沒有限制 includeu...