傳送門
兩個感受:碼量感人……大佬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...