题解

lct维护一个结束时间作为边权的最大生成树,每次出现奇环就找其中权值最小的那条边,删掉的同时还要把它标记上,直到这条边消失

如果有标记则输出No

边权通过建立虚点来维护

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 300005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,M,T,cnt;
struct E_node {
int u,v,s,t;
}E[MAXN];
vector<int> a[MAXN],b[MAXN];
bool vis[MAXN];
namespace lct {
struct node {
int lc,rc,fa,val,minq,siz;
bool rev;
}tr[MAXN];
#define lc(u) tr[u].lc
#define rc(u) tr[u].rc
#define fa(u) tr[u].fa
#define val(u) tr[u].val
#define minq(u) tr[u].minq
#define rev(u) tr[u].rev
#define siz(u) tr[u].siz
void Init() {
val(0) = minq(0) = 0x7fffffff;
for(int i = 1 ; i <= N ; ++i) {
val(i) = minq(i) = T + 2;
siz(i) = 1;
}
}
void reverse(int u) {
swap(lc(u),rc(u));
rev(u) ^= 1;
}
void pushdown(int u) {
if(rev(u)) {
reverse(lc(u));
reverse(rc(u));
rev(u) = 0;
}
}
void update(int u) {
minq(u) = val(u);
minq(u) = min(minq(u),minq(lc(u)));
minq(u) = min(minq(u),minq(rc(u)));
siz(u) = 1 + siz(lc(u)) + siz(rc(u));
} bool isRoot(int u) {
if(!fa(u)) return true;
else return rc(fa(u)) != u && lc(fa(u)) != u;
}
bool which(int u) {
return rc(fa(u)) == u;
}
void rotate(int u) {
int v = fa(u);
if(!isRoot(v)) {(v == lc(fa(v)) ? lc(fa(v)) : rc(fa(v))) = u;}
fa(u) = fa(v);fa(v) = u;
if(u == lc(v)) {lc(v) = rc(u);fa(rc(u)) = v;rc(u) = v;}
else {rc(v) = lc(u);fa(lc(u)) = v;lc(u) = v;}
update(v);
}
void Splay(int u) {
static int que[MAXN],qr;
qr = 0;int x;
for(x = u ; !isRoot(x) ; x = fa(x)) que[++qr] = x;
que[++qr] = x;
for(int i = qr ; i >= 1 ; --i) pushdown(que[i]);
while(!isRoot(u)) {
if(!isRoot(fa(u))) {
if(which(fa(u)) == which(u)) rotate(fa(u));
else rotate(u);
}
rotate(u);
}
update(u);
}
void Access(int u) {
for(int x = 0 ; u ; x = u , u = fa(u)) {
Splay(u);
rc(u) = x;
update(u);
}
}
void Makeroot(int u) {
Access(u);Splay(u);reverse(u);
}
void Link(int u,int v) {
Makeroot(u);Makeroot(v);Splay(v);fa(v) = u;
}
void Cut(int u,int v) {
Makeroot(u);Access(v);Splay(u);
if(rc(u) == v) {rc(u) = 0;fa(v) = 0;update(u);}
}
int dfs(int u) {
if(val(u) == minq(u)) return u;
pushdown(u);
if(minq(lc(u)) == minq(u)) return dfs(lc(u));
else return dfs(rc(u));
}
int Query(int u,int v) {
Makeroot(u);Access(v);Splay(u);
return dfs(u);
}
int Query_len(int u,int v) {
Makeroot(u);Access(v);Splay(u);
return siz(u);
}
bool Connected(int u,int v) {
Makeroot(u);Access(v);Splay(u);
int p = u;
while(rc(p)) p = rc(p);
if(p == v) return true;
return false;
}
}
using lct::Link;
using lct::Cut;
using lct::Makeroot;
using lct::Query;
using lct::Connected;
using lct::Query_len;
using lct::tr;
void Init() {
read(N);read(M);read(T);
lct::Init();
for(int i = 1 ; i <= M ; ++i) {
read(E[i].u);read(E[i].v);read(E[i].s);read(E[i].t);
a[E[i].s + 1].pb(i);b[E[i].t + 1].pb(i);
tr[i + N].siz = 1;tr[i + N].val = tr[i + N].minq = E[i].t;
}
}
void Solve() {
for(int i = 1 ; i <= T ; ++i) {
int s = a[i].size();
for(int j = 0 ; j < s ; ++j) {
int k = a[i][j];
if(E[k].u == E[k].v) {
if(!vis[k]) {vis[k] = 1;++cnt;}
}
else if(!Connected(E[k].u,E[k].v)) {Link(k + N,E[k].u);Link(k + N,E[k].v);}
else {
int t = Query(E[k].u,E[k].v);
if(tr[t].val > tr[k + N].val) t = k + N;
if((Query_len(E[k].u,E[k].v) / 2) % 2 == 0) {
if(!vis[t - N]) {vis[t - N] = 1;++cnt;}
}
if(t != k + N) {
Cut(t,E[t - N].u);Cut(t,E[t - N].v);
Link(k + N,E[k].u);Link(k + N,E[k].v);
}
}
}
s = b[i].size();
for(int j = 0 ; j < s ; ++j) {
int k = b[i][j];
Cut(E[k].u,k + N);Cut(E[k].v,k + N);
if(vis[k]) {vis[k] = 0;--cnt;}
}
if(cnt) puts("No");
else puts("Yes");
}
} int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
return 0;
}

【BZOJ】4025: 二分图的更多相关文章

  1. bzoj 4025 二分图 分治+并查集/LCT

    bzoj 4025 二分图 [题目大意] 有n个点m条边,边会在start时刻出现在end时刻消失,求对于每一段时间,该图是不是一个二分图. 判断二分图的一个简单的方法:是否存在奇环 若存在奇环,就不 ...

  2. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  3. BZOJ 4025: 二分图 [线段树CDQ分治 并查集]

    4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...

  4. BZOJ 4025 二分图(时间树+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4025 [题目大意] 给出一张图,有些边只存在一段时间,问在一个每个时间段, 这张图是否 ...

  5. bzoj 4025: 二分图

    Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. 解题报告: ...

  6. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  7. 「bzoj 4025: 二分图」

    题目 显然二分图没有奇环 于是考虑使用并查集维护一下看看是否存在奇环 我们可以考虑加权并查集,维护出\(x\)到\(fa_x\)的实际距离 由于我们只需要考虑奇偶性,于是我们处理出到根的路径异或一下就 ...

  8. 【刷题】BZOJ 4025 二分图

    Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input ...

  9. bzoj 4025 二分图 lct

    题目传送门 题解: 首先关于二分图的性质, 就是没有奇环边. 题目其实就是让你判断每个时段之内有没有奇环. 其次 lct 只能维护树,(反正对于我这种菜鸟选手只会维护树), 那么对于一棵树来说, 填上 ...

  10. BZOJ 4025 二分图 LCT维护最大生成树

    怎么说呢,我也不知道该咋讲,你就手画一下然后 yy 一下就发现这么做是对的. 为什么我明明都想出来了,却还是讲不出来啊~ #include <cstdio> #include <ve ...

随机推荐

  1. Spring Boot -Shiro配置多Realm

    核心类简介 xxxToken:用户凭证 xxxFilter:生产token,设置登录成功,登录失败处理方法,判断是否登录连接等 xxxRealm:依据配置的支持Token来认证用户信息,授权用户权限 ...

  2. 【模板】LCA

    代码如下 #include <bits/stdc++.h> using namespace std; const int maxn=5e5+10; inline int read(){ i ...

  3. 【codevs2205】等差数列

    题目大意:给定一个长度为 N 的序列,求这个序列中等差数列的个数. 题解:根据题意应该是一道序列计数 dp.设 \(dp[i][j]\) 表示以第 i 项结尾,公差为 j 的等差数列的个数,则状态转移 ...

  4. c读入实型

    读入: 如果读入的数为整型,然后转为实型,则%lf 否则%f也可以 读出: %f,这样在codeblocks才能看到正确的结果

  5. bzoj千题计划270:bzoj4559: [JLoi2016]成绩比较(拉格朗日插值)

    http://www.lydsy.com/JudgeOnline/problem.php?id=4559 f[i][j] 表示前i门课,有j个人没有被碾压的方案数 g[i] 表示第i门课,满足B神排名 ...

  6. ZSTU OJ 3770: 黑帽子 归纳总结

    Description 一群非常聪明的人开舞会,每人头上都戴着一顶帽子.帽子只有黑白两种,黑的至少有一顶.每个人都能看到其它人帽子的颜色,却看不到自己的.主持人先让大家 看看别人头上戴的是什幺帽子,然 ...

  7. LINQ 查询

    概述 事实上,对于LINQ to Objects来说,就是通过为IEnumerable<T>接口定义了一组约50个扩展方式来实现的. Lambda表达式(拉姆达表达式,Lambda Exp ...

  8. [ASP.NET]初试Web API

    Web API 1: 需要环境(VS2010/.Net4.0/MVC4 ) http://www.asp.net/web-api/overview/creating-web-apis/creating ...

  9. 第7月第20天 epoll

    1. ) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; ...

  10. matrix 矩阵(多维DP)

    题面 \(solution:\) 这一题其实就是一个非常明显的三维背包问题(但博主太弱了就10分QAQ) \(F[i][j][k]:\)表示走到\((i,j)\)这个位置并且背包容量为 \(k\) 时 ...