牛客多校1 1or2

2022-05-18 05:26:53 字數 3260 閱讀 6985

題意

給定一張n點m邊的圖,以及每個點的理想出入度,求是否能夠通過選擇某些邊來使得新圖上每個點的出入度為理想出入度

做法

由於d[i]的範圍為1~2,說明新圖中的連通分量要麼是鏈,要麼是環。對於此類最大匹配問題,可以用網路流來解決,但是由於可能存在奇環,這將導致找增廣路時,傳統的dinic演算法時間複雜度陡增。

如何處理帶奇環的圖最大匹配問題,可以使用帶花樹演算法來做,也就是一般圖最大圖匹配問題。

當兩個點的出入度都等於1時,直接把兩個點連起來

當兩個相連點的出入度都等於2時,把點點之間的連線,轉化成每個點拆成出入兩個點,把邊看做是乙個單獨的點,拆成出入兩個點,將每個點的出入點與夾邊的出入點相連線,並且將夾邊的入點連向出點

當相連的兩個點出入度有乙個為2乙個為1時,不僅將兩個點同時相連,還需要將出入度為1的點像出入度為2的點的出點連線。

如此我們可以構造出乙個一般圖

然後利用帶花樹演算法跑此圖的最大匹配

注意乙個特判,由於鏈有兩端,所以最後得到的點的總度數之和不可以為奇數。

最後判斷一下跑出來的最大匹配是否等於總度數之和即可

code

1 #include 2

#define dbg(x) cout << #x << "=" << x << endl

3#define eps 1e-8

4#define pi acos(-1.0)56

using

namespace

std;

7 typedef long

long

ll;8

9const

int inf = 0x3f3f3f3f;10

11 templateinline void read(t &res)

1217

18namespace

_buff

26return ib == ie ? -1 : *ib++;27}

28}2930

intqread()

38if (c == '-'

) 42

for (; c >= '

0' && c <= '

9'; c =getc())

45return pos ? ret : -ret;46}

4748

const

int maxn = 1e6 + 7;49

50int

n;51

intm, m1;

52int

ti;53

54//

一般圖最大匹配模板

5556

int fs[maxn], nt[maxn <<1

];57

int dt[maxn << 1

], pre[maxn], match[maxn];

58int

f[maxn], bz[maxn], bp[maxn], d[maxn];

5960

void link(int x,int

y)61

65int getf(int

k)66

69int lca(int x,int y)//

整個lca實現比較巧妙,由於是bfs,那麼這兩個點在當前奇環上的深度一定相等,交替暴力尋找lca即可。

7078

return

x;79}80

void make(int x,int y,int w)//

縮環(開花)過程

8190}91

bool find(int st)//

主過程92

96 d[d[0] = 1] = st,bz[st] = 1;97

int l = 0;98

while(l0

])99

113 bz[match[p]] = 1,d[++d[0]] = match[p];//

否則將其匹配點加入佇列

114}

115else

116121

}122

}123

return0;

124}

125//

一般圖最大匹配模板

126127

intidx[maxn],ide[maxn],deg[maxn];

128129

intmain()

141for ( int i = 1; i <= m; ++i )

148149

if(deg[u] == 1&& deg[v] == 1

)150

link(idx[u],idx[v]),link(idx[v],idx[u]);

151else

if(deg[u] == 2 && deg[v] == 2

) 160

else

164link(idx[v],idx[u]);link(idx[u],idx[v]);

165 link(idx[v]+1,idx[u]);link(idx[u],idx[v]+1

);166

}167

}168

if(sum & 1

)169 ok = 0

;170 n =ss;

171172

for ( int i = 1; i <= nn; ++i )

176if(deg[i] > 1 && !match[idx[i]+1

]) 179

}180

181for ( int i = 1; i <= nn; ++i )

187188

if(t != sum || ok == 0

) 191

else

194 m1 = 0

;195

for ( int i = 0; i <= n; ++i )

198 ti = 0

;199

}200

return0;

201}

202

2018 牛客多校 2

problem a problem b 考慮第二種優惠,每乙個物品如果原價購買了,那麼向可以免費拿的那個物品連一條邊 在樹上被指向的那個點是父親 如果不考慮環的話,考慮樹上dp。設 f i 0 表示買掉以 i 為根的子樹需要的最小花費,設 f i 0 表示買掉以 i 為根的子樹並且 i 這個點是原價...

牛客多校2 Cover the tree

題意 給定一棵無根樹,求用最少的鏈覆蓋樹上所有的邊,並輸出每條鏈的首位兩端編號 做法 首先確認需要多少條鏈來覆蓋所有邊。顯然,當n 1時,只需要一條,鏈頭尾編號都為1 當n 2時,需要一條,鏈頭尾為1,2 當n 3時,上述兩種情況鏈的頭尾都是入度為1的點,而確實,當從乙個葉子節點1出發,向上走到假定...

牛客多校2Eddy Walker 2

線性遞推的下界 bm演算法 複雜度 k 2 logn 正常矩陣快速冪 k 3 logn k 表示每一項由前k項遞推得到 n代表要得到的項 看到咖啡雞的 把前2 k 1項扔進去就可以了。include define maxn 100005 define inf 1000000000 define mo...