Portal

Description

初始时有\(n(n\leq10^5)\)个孤立的点,依次向图中加入\(m(m\leq3\times10^5)\)条带权无向边。使得图中每个点的度数均为奇数的边集是合法的,其权值定义为集合中的最大边权。每次加入边后,询问权值最小的合法边集的权值,不存在合法边集时输出\(-1\)。

Solution

存在合法边集 \(\Leftrightarrow\) 每个连通块的大小均为偶数。如果某连通块大小为奇数,那么该块的总度数是奇数,但一条无向边会提供两个度数,所以不存在合法边集。如果大小为偶数,那么可以按照如下的方式构造合法边集:

求出该连通块的一棵生成树。由深到浅观察每个点\(u\),如果\(u\)与\(\{ch_u\}\)的边中有偶数个在边集中,那么将边\((u,fa[u])\)加入边集。

做到根的时候,因为除了根以外有奇数个度数为奇数的点,但总度数为偶数,所以根的度数必然是奇数。

该方法将每个偶数连通块划分为了若干个偶数连通块。对于划分后的每个连通块,其最小生成树就是其权值最小的合法边集。

那么现在我们可以进行操作了。首先开一个set<pair<int,int>>记录lct中的边,first记录边权,second记录边的编号。初始用\(cnt\)表示剩余奇数连通块的个数,在其减至\(0\)前一直输出\(-1\)。

当存在合法边集后,加入边\((u,v)\)时,若\(u,v\)已经连通则维护最小生成树,否则在lct中连接\((u,v)\),同时维护set

如果该边被加入lct,那么尝试获得更优答案。从set中最大的边开始,检查能否移除这条边;若能移除则移除并检查次大,不能则break。因为如果当前的最大边不能移除,答案就不会变的更优了。最后输出set中最大的边权。

时间复杂度\(O(mlog(n+m))\)。

Code

//Pastoral Oddities
#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;
typedef pair<int,int> Ipair;
inline char gc()
{
static char now[1<<16],*S,*T;
if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
return *S++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
int const N=4e5+10;
int const INF=0x3F3F3F3F;
int n,m;
struct edge{int u,v;} ed[N];
set<Ipair> st;
int fa[N],ch[N][2],siz[N],isiz[N];
int val[N],maxL[N]; bool rev[N];
int wh(int p) {return p==ch[fa[p]][1];}
int notRt(int p) {return p==ch[fa[p]][wh(p)];}
void update(int p)
{
int ch0=ch[p][0],ch1=ch[p][1];
siz[p]=siz[ch0]+1+siz[ch1]+isiz[p];
int maxP=max(val[p],max(val[maxL[ch0]],val[maxL[ch1]]));
if(val[p]==maxP) maxL[p]=p;
else if(val[maxL[ch0]]==maxP) maxL[p]=maxL[ch0];
else if(val[maxL[ch1]]==maxP) maxL[p]=maxL[ch1];
}
void pushdw(int p) {if(rev[p]) swap(ch[p][0],ch[p][1]),rev[ch[p][0]]^=1,rev[ch[p][1]]^=1,rev[p]=false;}
void rotate(int p)
{
int q=fa[p],r=fa[q],w=wh(p);
fa[p]=r; if(notRt(q)) ch[r][wh(q)]=p;
fa[ch[q][w]=ch[p][w^1]]=q;
fa[ch[p][w^1]=q]=p;
update(q),update(p);
}
void pushRt(int p) {if(notRt(p)) pushRt(fa[p]); pushdw(p);}
void splay(int p)
{
pushRt(p);
for(int q=fa[p];notRt(p);rotate(p),q=fa[p]) if(notRt(q)) rotate(wh(p)^wh(q)?p:q);
}
void access(int p) {for(int q=0;p;q=p,p=fa[p]) splay(p),isiz[p]+=siz[ch[p][1]]-siz[q],ch[p][1]=q,update(p);}
void makeRt(int p) {access(p),splay(p),rev[p]^=1;}
void path(int p,int q) {makeRt(p),access(q),splay(q);}
void link(int i)
{
int p=ed[i].u,q=ed[i].v; makeRt(p),makeRt(q);
fa[p]=n+i,isiz[n+i]+=siz[p]; update(n+i);
fa[n+i]=q,isiz[q]+=siz[n+i]; update(q);
}
void clear(int p) {fa[p]=ch[p][0]=ch[p][1]=0,isiz[p]=0; update(p);}
void cut(int i)
{
int p=ed[i].u,q=ed[i].v; path(p,q);
fa[p]=ch[p][1]=0; ch[q][0]=0;
clear(n+i); update(p),update(q);
}
int find(int p) {access(p),splay(p); while(ch[p][0]) p=ch[p][0]; return p;}
int odd(int p) {return siz[p]+1>>1&1;}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++) val[i]=-INF,update(i);
for(int i=1,cnt=n;i<=m;i++)
{
int u=read(),v=read(),w=read();
ed[i].u=u,ed[i].v=v; val[n+i]=w,maxL[n+i]=n+i;
if(find(u)==find(v))
{
path(u,v); int id=maxL[v]-n,w0=val[id+n];
if(w<w0) cut(id),link(i),st.erase(make_pair(w0,id));
else {printf("%d\n",cnt?-1:st.rbegin()->first); continue;}
}
else
{
makeRt(u),cnt-=odd(u); makeRt(v),cnt-=odd(v);
link(i),cnt+=odd(v);
}
st.insert(make_pair(val[i+n],i));
if(cnt) {puts("-1"); continue;}
while(true)
{
int id=st.rbegin()->second; u=ed[id].u,v=ed[id].v;
path(u,v); if(odd(u)) break;
cut(id); st.erase(*st.rbegin());
}
printf("%d\n",st.rbegin()->first);
}
return 0;
}

P.S.

第一次用set,不大懂...%%%zhx

Codeforces603E - Pastoral Oddities的更多相关文章

  1. CF603E Pastoral Oddities

    CF603E Pastoral Oddities 度数不好处理.转化题意:不存在连通块为奇数时候就成功了(自底向上调整法证明) 暴力:从小到大排序加入.并查集维护.全局变量记录奇数连通块的个数 答案单 ...

  2. 【CF603E】Pastoral Oddities cdq分治+并查集

    [CF603E]Pastoral Oddities 题意:有n个点,依次加入m条边权为$l_i$的无向边,每次加入后询问:当前图是否存在一个生成子图,满足所有点的度数都是奇数.如果有,输出这个生成子图 ...

  3. Codeforces 603E Pastoral Oddities

    传送门:http://codeforces.com/problemset/problem/603/E [题目大意] 给出$n$个点,$m$个操作,每个操作加入一条$(u, v)$长度为$l$的边. 对 ...

  4. CF603E Pastoral Oddities 优先队列+结论+LCT维护生成树

    首先,一个神奇的结论:一个合法的方案存在的条件是每一个联通块的节点数都是偶数个的. 这个可以用数学归纳法简单证一证. 证出这个后,我们只需动态加入每一个边,并查看一下有哪些边能够被删除(删掉后联通块依 ...

  5. cf Round 603

    A.Alternative Thinking(思维) 给出一个01串,你可以取反其中一个连续子串,问取反后的01子串的最长非连续010101串的长度是多少. 我们随便翻一个连续子串,显然翻完之后,对于 ...

  6. CF603EPastoral Oddities

    /* LCT管子题(说的就是你 水管局长) 首先能得到一个结论, 那就是当且仅当所有联通块都是偶数时存在构造方案 LCT动态加边, 维护最小生成联通块, 用set维护可以删除的边, 假如现在删除后不影 ...

  7. ccpc 2018 final G - Pastoral Life in Stardew Valley

    #include <iostream> #include<cstdio> #include<cstring> #include<queue> using ...

  8. On having layout

    英文原文在此:http://www.satzansatz.de/cssd/onhavinglayout.htm 介绍 Internet Explorer 中有很多奇怪的渲染问题可以通过赋予其“layo ...

  9. poj1984 带权并查集(向量处理)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5939   Accepted: 2 ...

随机推荐

  1. ubuntu下安装apcu扩展

    apcu前身是apc,apc分为系统缓存和用户缓存 1.系统缓存是指PHP执行时增加缓存,减少PHP文件的反复检查和编译,从而达到系统加速的目的. 2.用户缓存是指,PHP代码中将数据写入缓存,是用户 ...

  2. Summary of 2016 International Trusted Computing and Cloud Security Summit

    1)      Welcome Remarks 2)      The advancement of Cloud Computing and Tursted Computing national st ...

  3. Javaweb学习笔记5—Cookie&Session

    今天来讲javaweb的第五阶段学习. Cookie和Session同样是web开发常用到的地方. 老规矩,首先先用一张思维导图来展现今天的博客内容. ps:我的思维是用的xMind画的,如果你对我的 ...

  4. How To Build Kubernetes Platform (构建Kubernetes平台方案参考)

    Architecture Architecture Diagram Non-Prod Environment Prod Environment Cluster Networking Container ...

  5. stay hungry stay foolish.

    I am honored to be with you today at your commencement from one of the finest universities in the wo ...

  6. 1-jdk的安装与配置

    1- Jvm.jdk.jre之间的关系 JVM:Java虚拟机,保证java程序跨平台.(Java Virtual Machine) JRE: Java运行环境,包含JVM和核心类库.如果只是想运行j ...

  7. PHP100视频教程-->视频下载

    链接:https://pan.baidu.com/s/14tbX1rz3hYSKY6k0T6WVzg提取码:kypy PHP是一种目前最流行的服务端Web程序开发语言之一.PHP主要的特点是语法简单易 ...

  8. POJ-2442-Sequence(二叉堆)

    POJ-2442 Description Given m sequences, each contains n non-negative integer. Now we may select one ...

  9. DNS域名系统

    1. 什么是DNS? DNS是域名系统的缩写,DNS通过将域名与实际的Web服务器连接来帮助引导Internet上的流量.从本质上讲,它需要一个人性化的请求 – 像simcf.cc这样的域名 – 并将 ...

  10. Centos 7 编译php 7.2.10

    步骤一:安装依赖 yum install -y wget gcc gcc-c++ gd-devel zlib-devel libjpeg-devel libpng-devel libiconv-dev ...