給定乙個邊帶正權的連通無向圖g=(v,e),其中n=|v|,m=|e|,n個點從1到n依次編號,給定三個正整數u,v,和l (u≠v),假設現在加入一條邊權為l的邊(u,v),那麼需要刪掉最少多少條邊,才能夠使得這條邊既可能出現在最小生成樹上,也可能出現在最大生成樹上?
第一行包含用空格隔開的兩個整數,分別為n和m;
接下來m行,每行包含三個正整數u,v和w表示圖g存在一條邊權為w的邊(u,v)。
最後一行包含用空格隔開的三個整數,分別為u,v,和 l;
資料保證圖中沒有自環。
輸出一行乙個整數表示最少需要刪掉的邊的數量。
3 23 2 1
1 2 3
1 2 2
1對於20%的資料滿足n ≤ 10,m ≤ 20,l ≤ 20;
對於50%的資料滿足n ≤ 300,m ≤ 3000,l ≤ 200;
對於100%的資料滿足n ≤ 20000,m ≤ 200000,l ≤ 20000。
正解:最小割。
講道理這題並不難,但是我完全沒往最小割那方面去想,於是做不出。。
我們知道,要使$(u,v,w)$在最小生成樹上,必須割掉邊權小於$w$的一些邊,使得$u,v$不連通,最大生成樹同理。
於是我們對於小於$w$的邊連起來,跑一遍最小割,大於$w$的同理。兩個最小割加起來,就是答案了。
1//it is made by wfj_2048~
2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include
13#define inf (1<<30)
14#define n (500010)
15#define il inline
16#define rg register
17#define ll long long
18#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
1920
using
namespace
std;
2122
struct edgeg[n];
23struct ee[n];
2425
inthead[n],d[n],q[n],n,m,u,v,w,num,ans;
2627 il int
gi()
3435 il void insert(rg int
from,rg int to,rg int
cap),head[from]=num; return;37
}3839 il int cmp(const e &a,const e &b)
4041 il int bfs(rg int s,rg int
t)52}53
}54return0;
55}5657 il int dfs(rg int x,rg int t,rg int
a)64 g[i].flow+=f,g[i^1].flow-=f;
65 flow+=f,a-=f; if (!a) break;66
}67}68
return
flow;69}
7071 il int maxflow(rg int s,rg int
t)76
77 il void
work()
85 ans+=maxflow(u,v),memset(head,0,sizeof(head)),num=1;86
for (rg int i=m;i;--i)
90 ans+=maxflow(u,v); printf("
%d\n
",ans); return;91
}9293int
main()
bzoj 2561 最小生成樹
給定乙個邊帶正權的連通無向圖g v,e 其中n v m e n個點從1到n依次編號,給定三個正整數u,v,和l u v 假設現在加入一條邊權為l的邊 u,v 那麼需要刪掉最少多少條邊,才能夠使得這條邊既可能出現在最小生成樹上,也可能出現在最大生成樹上?第一行包含用空格隔開的兩個整數,分別為n和m 接...
bzoj2561 最小生成樹
time limit 10 sec memory limit 128 mb submit 1024 solved 520 submit status discuss 給定乙個邊帶正權的連通無向圖g v,e 其中n v m e n個點從1到n依次編號,給定三個正整數u,v,和l u v 假設現在加入一...
bzoj 2561 最小生成樹
給定乙個邊帶正權的連通無向圖,現在加入一條邊權為l的邊 u,v 那麼需要刪掉最少多少條邊,才能夠使得這條邊既可能出現在最小生成樹上,也可能出現在最大生成樹上?以前看著一臉懵逼,現在好像就是那樣。容易想到,當u v存在一條路徑,上面不存在 l的邊,那麼新邊一定不在最小生成樹上,所以將所有小於l的邊建出...