乙個人有 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序,需要剖分一下。但是我不會,所以去學了一下...