日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CF603E-Pastoral Oddities【CDQ分治,可撤销并查集】

發布時間:2023/12/3 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF603E-Pastoral Oddities【CDQ分治,可撤销并查集】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/CF603E


題目大意

開始時有nnn個點,沒有邊。

依次加入mmm條帶權的邊,每次加入后詢問是否存在一個邊集,滿足每個點的度數均為奇數,求使得這個邊集的最大權值最小。

1≤n≤105,1≤m≤3×1051\leq n\leq 10^5,1\leq m\leq 3\times 10^51n105,1m3×105


解題思路

首先考慮存在這個邊集的條件,可以證明存在滿足條件的邊集的充要條件是聯通塊的大小都是偶數。
必要性:對于一個聯通塊,因為每條邊都會貢獻偶數個度數,而如果這個連通塊是奇數個點,那么如果合法的總度數就是 奇數×奇數=奇數 ,顯然不可能是偶數,所以不存在這種情況。
充分性:如果存在一個點的度數為奇數,那么這個聯通快里也至少有一個點的度數是奇數,我們順路刪掉這兩個點路徑上的邊就可以調整到合法情況。

而我們能連邊就連邊肯定是最優的,因為不存在一種連邊會使得奇數連通塊數變多。

然后考慮用CDQ分治解決這題,注意到答案肯定是單調不升的,我們的流程是記錄目前區間[l,r][l,r][l,r]的答案區間{L,R}\{L,R\}{L,R}

先計算出ansmidans_{mid}ansmid?,那么此時我們就可以分為[l,mid?1]{ansmid,R}[l,mid-1]\{ans_{mid},R\}[l,mid?1]{ansmid?,R}[mid+1,r]{L,ansmid}[mid+1,r]\{L,ans_{mid}\}[mid+1,r]{L,ansmid?}

此時兩個區間都被分開,這提示我們暴力枚舉這些區間就是正常分治的復雜度。

那么做法就很顯然了,我們算出ansmidans_{mid}ansmid?后左右兩邊遞歸處理,用可撤銷并查集處理。

時間復雜度:O(mlog?mlog?n)O(m\log m\log n)O(mlogmlogn)


code

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=3e5+10; struct node{int x,y,w,id; }a[N],b[N]; struct clnode{int x,y,siz,dep; }cl[N]; int n,m,sum,clt,fa[N],siz[N],dep[N]; int ans[N],rk[N]; int find(int x) {return (fa[x]==x)?x:find(fa[x]);} void unionn(int x,int y){x=find(x);y=find(y);if(x==y)return;if(dep[x]>dep[y])swap(x,y);cl[++clt]=(clnode){x,y,siz[y],dep[y]};sum-=(siz[x]&1)&(siz[y]&1);fa[x]=y;siz[y]+=siz[x];dep[y]=max(dep[y],dep[x]+1); } void clearto(int d){while(clt>d){int x=cl[clt].x,y=cl[clt].y;siz[y]=cl[clt].siz;dep[y]=cl[clt].dep;sum+=(siz[x]&1)&(siz[y]&1);fa[x]=x;clt--;}return; } void cdq(int l,int r,int L,int R){if(l>r)return;int mid=(l+r)>>1,now=clt;for(int i=l;i<=mid;i++)if(rk[i]<L)unionn(a[i].x,a[i].y);int mow=clt;for(int i=L;i<=R;i++){if(b[i].id<=mid)unionn(b[i].x,b[i].y);if(!sum){ans[mid]=i;break;}}if(!ans[mid]){clearto(mow);cdq(mid+1,r,L,R);return;}clearto(mow);cdq(mid+1,r,L,ans[mid]);clearto(now);for(int i=L;i<ans[mid];i++)if(b[i].id<l)unionn(b[i].x,b[i].y);cdq(l,mid-1,ans[mid],R);clearto(now);return; } bool cmp(node x,node y) {return x.w<y.w;} int main() {scanf("%d%d",&n,&m);sum=n/2;if(n&1){for(int i=1;i<=m;i++)puts("-1");return 0;}for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1;for(int i=1;i<=m;i++){scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);a[i].id=i;b[i]=a[i];}sort(b+1,b+1+m,cmp);for(int i=1;i<=m;i++)rk[b[i].id]=i;cdq(1,m,1,m);for(int i=1;i<=m;i++)if(!ans[i])puts("-1");else printf("%d\n",b[ans[i]].w);return 0; }

總結

以上是生活随笔為你收集整理的CF603E-Pastoral Oddities【CDQ分治,可撤销并查集】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。