牛客練習賽51 F 發傳單 網路流

2021-09-27 04:36:41 字數 1595 閱讀 7680

乙個人有 n

nn 個朋友,這個人有很多傳單,他可以將傳單發給所有朋友,對於發給第 i

ii 個人需要 w

iw_i

wi​ 的費用,他的朋友之間也有相互認識可以將傳單給其他人,也需要一些費用,告訴你具體的朋友之間的認識關係和費用,要求這個人在使用最少的傳單數下用最少的總費用,使得朋友都看過傳單。

由於要求每乙個朋友都看過,那麼可以將每乙個朋友進行拆點 (i,

i+n)

(i,i+n)

(i,i+n

) 那麼這兩點之間的流量一定要大於等於 1

11 ,將人做為源點 s

ss 按照題意建邊,建立乙個匯點 t

tt ,向所有的朋友右端點連向 t

tt ,由於要求使用最小的傳單數,參考一血的**,可以將人向每乙個朋友傳單的費用變為 wi+

in

fw_i+inf

wi​+in

f ,最後 ans

%inf

ans\%inf

ans%in

f 就行了,因為是最小費用,所以可以使得所用的傳單最小。現在就只要建立超級源點 s

ss 和超級匯點 t

tt 就可以跑有上下界的最小費用最大流了。

#include

#define inf 0x3f3f3f3f

using

namespace std;

const

int n=

1e5+10;

const

int m=

1e6+10;

const

int mx=

2e6;

struct mcmf

void

addedge

(int x,

int y,

int z,

int c)

intbfs()

}}if(

!pre[t]

)return0;

x=t;ans+

=dis[t]

*liu[t]

;while

(x!=s)

return1;

}int

mcmf()

return ans;

}}f;

int d[n]

;void

add(

int u,

int v,

int down,

int up,

int w)

int n,s,t,s,t;

intmain()

for(

int i=

1;i<=n;i++)}

for(

int i=

1;i<=t;i++)if

(d[i]

>

0)f.

addedge

(s,i,d[i],0

);else

if(d[i]

<

0)f.

addedge

(i,t,

-d[i],0

);cout

%mx<}

牛客練習賽51

theme 給定n與m,要求你用正整數填充n個元素,使得這n個元素的和 m,定義喜愛度為i的個數使得2 i n且a i a i 1 1。1 n 1e5,1 m 1e9 solution 構造題。考慮列舉分成幾個段i,若某段的長度為len,則該段的數為1 len,可知喜愛度應為n i,所以我們的目標是...

題解 牛客練習賽51

字首a的數量,字尾c的數量,遇到b就計算一次答案。includeusing namespace std typedef long long ll const int n 1e5 100 char s n int cnt n int main int tmp 0 for int i 1 i n i p...

牛客練習賽58 F

求帶單點修改的樹上兩點間任意子路徑長異或和。路徑長等於路徑上所有異或和。簡單模擬一下,可以發現。奇數情況下,答案是偶數點異或和。偶數情況下,就是正常的異或和。偶數點異或和也很容易處理。分深度奇偶樹狀陣列即可。但是這是對於鏈的,不能直接dfs dfsdf s序,需要剖分一下。但是我不會,所以去學了一下...