題目鏈結
題意
n點m條邊的無向圖,每個點的點權是ai,沒經過一次點,點權增加bi,即第k次經過i點權值為ai + (k - 1) * bi,現給出q個xi和q個yi,每次從中選出一組xi,yi,統計從xi到yi的代價和(代價為從xi到yi經過的所有點的點權和),每個點只能選一次,q次後(也就是全選完),求最小代價。
思路
考慮最小費用最大流。
重點解決幾個問題:
①點權改邊權。拆點,乙個點拆成乙個入點和乙個出點,點權就改為了從入點到出點的邊權。
②每經過一次點,權值增加。在網路流裡,可以用拆點,入點和出點間的容量為1來限制該點只能走一次,那麼如果要限制走q次,可以從入點到出點連q條邊,容量為1,費用為ai,ai+bi,ai+2*bi…
③q組起點和終點每個點只能選一次。建乙個超級源點s和乙個超級匯點t,從s到每個xi連一條容量為1的邊,yi到t連一條容量為1的邊,這樣就可以保證每個點只選一次。
#include
#define inf 0x3f3f3f3f
using
namespace std;
const
int n =
5e3+7;
const
int m =
1e4+7;
const
int maxn =
5e3+7;
typedef
long
long ll;
int maxflow, mincost;
struct edge ;}
;struct mcmf
void
add(
int from,
int to,
int cap,
int cost)
bool
spfa
(int s,
int t,
int&flow,
int&cost)}}
}if(d[t]
== inf)
return
false
; flow +
= a[t]
; cost +
= d[t]
* a[t]
;int u = t;
while
(u != s)
return
true;}
intminmaxflow
(int s,
int t)};
intmain()
}for
(int i =
1, x, y; i <= m; i++
)for
(int i =
1, x; i <= q; i++
)//從源點到xi建容量為1,費用為0的邊
scanf
("%d"
,&x)
, solve.
add(s, x,1,
0);for
(int i =
1, x; i <= q; i++
)//從yi到t建容量為1,費用為0的邊
scanf
("%d"
,&x)
, solve.
add(x + n, t,1,
0); solve.
minmaxflow
(s, t)
;printf
("%d\n"
, mincost)
;}
牛客練習賽65水題
powered by ab in 局外人 純模擬題。mod 998244353 n int input s list map int input split s.sort if n 1 lst s n 2 1 tmp s n 2 1 ans 1for i in tmp ans ans i mod p...
牛客20180601練習賽19 E
已知第i個瓶子的品牌為ai,且其能開啟bi品牌的瓶子.問有幾瓶飲料托公尺無法喝到.被用於開啟飲料瓶的瓶子不一定需要被開啟.乙個瓶子不能開啟其本身.輸入描述 第一行乙個整數n,表示飲料的瓶數.接下來n行,每行兩個整數ai,bi.輸出描述 輸出一行乙個整數,表示小托公尺無法喝到的飲料瓶數.示例1 輸入 ...
牛客網練習賽24 E青蛙
有乙隻可愛的老青蛙,在路的另一端發現了乙個黑的東西,想過去一 竟。於是便開始踏上了旅途 一直這個小路上有很多的隧道,從隧道的a進入,會從b出來,但是隧道不可以反向走。這只青蛙因為太老了,所以很懶,現在想請你幫幫慢,問他最少需要幾步才可以到達對面。將小徑看作一條數軸,青蛙初始在0上,這只青蛙可以向前跳...