CF19E Fairy 樹形結構,差分

2022-09-14 15:00:20 字數 1140 閱讀 5272

給出\(n\)個點\(m\)條邊的一張無向圖,求有多少條邊去掉後可以使得圖變成一張二分圖。

\(1\leq n,m\leq 10^4\)

雖然線段樹分治可以暴力草過去但是考慮點智慧型的做法。

眾所周知沒有奇環是圖是二分圖的充要條件,所以答案就是奇環的交。

顯然無法考慮所有的奇環,但是我們可以考慮一下簡單奇環。

先隨便跑出乙個生成樹,然後列舉所有非樹邊考慮其在樹上的環,只考慮樹邊的話答案肯定是所有簡單奇環的交。並且這條邊不能出現在乙個列舉出的偶環上,因為如果這條邊即在乙個奇環又在乙個偶環上,那麼這兩個環的不交部分一定是乙個奇環,所以這條邊就不成立了。

然後對於非樹邊,顯然條件就是這條邊必須得是唯一乙個樹上奇環的邊。

用\(dfs\)搜出生成樹,此時所有的非樹邊都是返祖邊,這樣我們就可以用樹上差分計算樹邊的條件了。

時間複雜度\(o(n+m)\)(不算答案用的排序)

#include#include#includeusing namespace std;

const int n=1e4+10;

struct nodea[n<<1];

int n,m,tot,cnt,ant,last;

int ls[n],v[n],s[n],from[n],ans[n];

void addl(int x,int y,int w)

void dfs(int x)

else if(!v[y])

} return;

}int main()

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

if(!v[i])v[i]=1,dfs(i);

if(!cnt)

if(cnt==1)ans[++ant]=last;

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

if(s[i]==cnt)ans[++ant]=a[from[i]].w;

sort(ans+1,ans+1+ant);

ant=unique(ans+1,ans+1+ant)-ans-1;

printf("%d\n",ant);

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

printf("%d ",ans[i]);

return 0;

}

CF 19D Points 線段樹 平衡樹

在平面上進行三種操作 1 add x y 在平面上新增乙個點 x,y 2 remove x y 將平面上的點 x,y 刪除 3 find x y 在平面上尋找乙個點,使這個點的橫座標大於x,縱座標大於y,而且要求他的橫座標盡量小,如果有多個點滿足,則選取橫座標盡量小的前提下,縱座標最小的點。方法 將...

CF 19D Points 線段樹 平衡樹

在平面上進行三種操作 1 add x y 在平面上新增乙個點 x,y 2 remove x y 將平面上的點 x,y 刪除 3 find x y 在平面上尋找乙個點,使這個點的橫座標大於x,縱座標大於y,而且要求他的橫座標盡量小,如果有多個點滿足,則選取橫座標盡量小的前提下,縱座標最小的點。方法 將...

CF487E Tourists(園方樹 樹鏈剖分)

園方樹 樹鏈剖分 這題首先容易得到的性質是,乙個點雙內的所有點互相到達,這就說明這個點雙的答案就是他們中的最小值,因此建立園方樹。方點就維護了最值 現在有修改問題,對於乙個圓點的修改,勢必要影響到方點,我們對每個方點維護乙個multiset,這樣對於每個圓點的修改,都是對他的父親方點進行修改,這樣可...