bzoj4316 小C的獨立集

2022-05-02 05:30:09 字數 1723 閱讀 3470

圖論小王子小c經常虐菜,特別是在圖論方面,經常把小d虐得很慘很慘。

這不,小c讓小d去求乙個無向圖的最大獨立集,通俗地講就是:在無向圖中選出若干個點,這些點互相沒有邊連線,並使取出的點盡量多。

小d雖然圖論很弱,但是也知道無向圖最大獨立集是npc,但是小c很仁慈的給了乙個很有特點的圖: 圖中任何一條邊屬於且僅屬於乙個簡單環,圖中沒有重邊和自環。小c說這樣就會比較水了。

小d覺得這個題目很有趣,就交給你了,相信你一定可以解出來的。

第一行,兩個數n, m,表示圖的點數和邊數。

第二~m+1行,每行兩個數x,y,表示x與y之間有一條無向邊。

輸出這個圖的最大獨立集。

5 61 2

2 33 1

3 44 5

3 52

100% n <=50000, m<=60000

正解:仙人掌$dp$。

這題是騎士的加強版,也是沒有上司的舞會的超級加強版。。也是我第一棵獨立寫出來的仙人掌。。

這題做法和騎士類似,我們只要把環單獨摳出來,然後分別強制不選環邊上的兩個點,跑最大獨立集,然後再合併到仙人掌上就行了。

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 #include

14#define inf (1<<30)

15#define n (50010)

16#define il inline

17#define rg register

18#define ll long long

19#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

2021

using

namespace

std;

2223

struct edgeg[200010

];24

25int head[n],fa[n],dep[n],dfn[n],low[n],vis[n],f[2][n],ff[2

][n],n,m,num,cnt;

2627 il int

gi()

3435 il void insert(rg int

from,rg int

to),head[from]=num; return;37

}3839 il void dp(rg int x,rg int rt,rg int dep,rg int

tot)

47if (x==rt) ff[1][x]=0; return;48

}4950 il void circle(rg int rt,rg int

x)66

67 il void dfs(rg int x,rg int

p)76

for (rg int i=head[x];i;i=g[i].nt)

80return;81

}8283 il void

work()

89 dfs(1,0); printf("

%d",max(f[0][1],f[1][1])); return;90

}9192int

main()

BZOJ 4316 小C的獨立集

4316 小c的獨立集 思路 先將樹上的轉移做好。然後環上的轉移就是強制最上面的的點選或者不選,然後在環上跑一遍轉移就可以了。pragma gcc optimize 2 pragma gcc optimize 3 pragma gcc optimize 4 includeusing namespac...

bzoj 4316 小C的獨立集 樹形dp

仙人掌樹形dp。令f x 0 表示以x為根的子樹中,不選x的最大值 f x 1 表示選x的最大值。注意到,同乙個環中的所有點,只有在dfs樹中最高的那個點才會對所在環之外的點的f值造成影響。因此我們在最高的那個點做乙個dp,然後就得到了最高那個點的f,而這個環中的其他點的f就不用管了。ac 如下 i...

BZOJ4316 小C的獨立集(動態規劃)

bzoj 考慮樹的獨立集求法 設 f i 0 1 表示 i 這個點一定不選,以及 i 這個點無所謂的最大值 轉移 f u 0 sum f v 1 f u 1 sum f v 0 f u 1 max f u 1 f u 0 現在放在了仙人掌上,我們可以看做一棵樹加上了若干不相交的返祖邊 於是再加上一維...