牛客練習賽65 E 網路流 點權改變的處理方法

2021-10-07 12:05:07 字數 1799 閱讀 2014

題目鏈結

題意

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上,這只青蛙可以向前跳...