三倍經驗,三個條件,分別對應了常見的3種模型,第一種是限制每個點只能一次且無交點,我們可以把這個點拆成乙個出點乙個入點,capacity為1,這樣就限制了只選擇一次,第二種是可以有交點,但不能有交邊,那我們就不需要拆點,限制每條capacity都為1就可以了,第三種直接連,沒有限制(
#includeusingnamespace
std;
#define lowbit(x) ((x)&(-x))typedef
long
long
ll;const
int maxm = 1e6+5
;const
int inf = 0x3f3f3f3f
;struct
edge edges[maxm];
int head[maxm], cur[maxm], cnt, fa[maxm], d[maxm], buf[43][43], num[43][43
], id;
bool
inq[maxm];
void
init()
void add(int u, int v, int cap, int
cost) ;
head[u] = cnt++;
}void addedge(int u, int v, int cap, int
cost)
bool spfa(int s, int t, int &flow, ll &cost) }}
}if(d[t] == inf) return
false
; flow +=cur[t];
cost += 1ll*d[t]*cur[t];
for(int u = t; u != s; u =edges[fa[u]].u)
return
true;}
int mincostmaxflow(int s, int t, ll &cost)
void
run_case()
for(int i = m; i < n+m-1; ++i)
}for(int i = 1; i <= m; ++i) addedge(s, num[m][i]<<1, 1, 0
);
for(int i = 1; i < n+m; ++i) addedge((num[n+m-1][i]<<1)|1, t, 1, 0
); ll cost = 0
; mincostmaxflow(s, t, cost);
cout
<< -cost << "\n"
;
//second
init();
for(int i = m; i < n+m-1; ++i)
for(int j = 1; j <= i; ++j)
for(int i = 1; i <= m; ++i) addedge(s, num[m][i], 1, -buf[m][i]);
for(int i = 1; i < n+m; ++i) addedge(num[n+m-1][i], t, inf, 0
); cost = 0
, mincostmaxflow(s, t, cost);
cout
<< -cost << "\n"
;
//third
init();
for(int i = m; i < n+m-1; ++i)
for(int j = 1; j <= i; ++j)
for(int i = 1; i <= m; ++i) addedge(s, num[m][i], 1, -buf[m][i]);
for(int i = 1; i < n+m; ++i) addedge(num[n+m-1][i], t, inf, 0
); cost = 0
, mincostmaxflow(s, t, cost);
cout
<< -cost << "\n"
;}intmain()
P4013 數字梯形問題 網路流
給定乙個由 nn 行數字組成的數字梯形如下圖所示。梯形的第一行有 mm 個數字。從梯形的頂部的 mm 個數字開始,在每個數字處可以沿左下或右下方向移動,形成一條從梯形的頂至底的路徑。分別遵守以下規則 從梯形的頂至底的 mm 條路徑互不相交 從梯形的頂至底的 mm 條路徑僅在數字結點處相交 從梯形的頂...
洛谷P4013 數字梯形問題(費用流)
傳送門 兩個感受 碼量感人 大佬nb 規則一 m 條路徑都不相交,那麼每乙個點只能經過一次,那麼考慮拆點,把每乙個點拆成 a 和 b 然後兩點之間連一條容量 1 費用該點本身數值的邊,表明這個點只能被選一次,然後每乙個點的 b 向它能到達的點的 a 連邊,表明能從這個點到另乙個點,容量隨意,費用 0...
luoguP1043數字遊戲
丁丁最近沉迷於乙個數字遊戲之中。這個遊戲看似簡單,但丁丁在研究了許多天之後卻發覺原來在簡單的規則下想要贏得這個遊戲並不那麼容易。遊戲是這樣的,在你面前有一圈整數 一共n個 你要按順序將其分為m個部分,各部分內的數字相加,相加所得的m個結果對10取模後再相乘,最終得到乙個數k。遊戲的要求是使你所得的k...