【CodeForces19E】Fairy
Description
给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成
一个二分图。
Input
第 1 行包含两个整数 n,m。分别表示点数和边数。
第 2 到 m+1 行每行两个数 x,y 表示有一条(x,y)的边。
Output
输出第一行一个整数,表示能删除的边的个数。
接下来一行按照从小到大的顺序输出边的序号。
Sample Input
4 4
1 2
1 3
2 4
3 4
Sample Output
4 1
2 3 4
HINT
10%的数据,n,m<=10
40%的数据,n,m<=1000
100%的数据,n,m<=100000
改了改4025就行了
辣鸡出题人听说我用LCT之后把数据范围加强到了10^6
QAQ然后LCT被卡常了.(链剖能A
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 300010
#define GET (ch>='0'&&ch<='9')
#define MAXINT 0x3f3f3f3f
#define is_root(x) (tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x)
using namespace std;
int n,m,T,Top,cnt;
int ans[MAXN<<1];
int sta[MAXN<<1],top;
int In[MAXN<<1],on[MAXN<<1];
struct splay
{int ch[2],fa,minn,st,sum,val;bool rev;
}tree[MAXN<<1];
inline void in(int &x)
{char ch=getchar();x=0;while (!GET) ch=getchar();while (GET) x=x*10+ch-'0',ch=getchar();
}
struct edge { int u,v,w; }e[MAXN];
struct Edge
{int to;Edge *next;
}E[MAXN<<1],*prev1[MAXN],*prev2[MAXN];
void insert1(int u,int v) { E[++Top].to=v;E[Top].next=prev1[u];prev1[u]=&E[Top]; }
void insert2(int u,int v) { E[++Top].to=v;E[Top].next=prev2[u];prev2[u]=&E[Top]; }
void push_down(int x)
{if (tree[x].rev){tree[tree[x].ch[0]].rev^=1,tree[tree[x].ch[1]].rev^=1;swap(tree[x].ch[0],tree[x].ch[1]);tree[x].rev^=1;}
}
void push_up(int x)
{tree[x].minn=tree[x].val;tree[x].st=x;tree[x].sum=x>n;if (tree[x].ch[0]){if (tree[tree[x].ch[0]].minn<tree[x].minn) tree[x].minn=tree[tree[x].ch[0]].minn,tree[x].st=tree[tree[x].ch[0]].st;tree[x].sum+=tree[tree[x].ch[0]].sum;}if (tree[x].ch[1]){if (tree[tree[x].ch[1]].minn<tree[x].minn) tree[x].minn=tree[tree[x].ch[1]].minn,tree[x].st=tree[tree[x].ch[1]].st;tree[x].sum+=tree[tree[x].ch[1]].sum;}
}
void rot(int x)
{int y=tree[x].fa,z=tree[y].fa,l,r;l=(tree[y].ch[1]==x);r=l^1;if (!is_root(y)) tree[z].ch[tree[z].ch[1]==y]=x;tree[tree[x].ch[r]].fa=y;tree[y].fa=x;tree[x].fa=z;tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y;push_up(y);push_up(x);
}
void Splay(int x)
{top=0;sta[++top]=x;for (int i=x;!is_root(i);i=tree[i].fa) sta[++top]=tree[i].fa;while (top) push_down(sta[top--]);while (!is_root(x)){int y=tree[x].fa,z=tree[y].fa;if (!is_root(y)){if ((tree[y].ch[0]==x)^(tree[z].ch[0]==y)) rot(x);else rot(y);}rot(x);}
}
void access(int x) { for (int i=0;x;i=x,x=tree[x].fa) Splay(x),tree[x].ch[1]=i,push_up(x); }
void make_root(int x) { access(x);Splay(x);tree[x].rev^=1; }
void link(int x,int y) { make_root(x);tree[x].fa=y; }
void cut(int x,int y) { make_root(x);access(y);Splay(y);tree[y].ch[0]=tree[x].fa=0;push_up(y); }
void split(int x,int y) { make_root(x);access(y);Splay(y); }
int find_root(int x) { for (access(x),Splay(x);tree[x].ch[0];x=tree[x].ch[0]); return x; }
void ins(int x)
{int u=e[x].u,v=e[x].v;if (u==v) { In[x]=1;cnt++;return; }if (find_root(u)!=find_root(v)) on[x]=1,link(u,x+n),link(v,x+n);else{split(u,v);int y=tree[v].st-n;if (e[y].w<e[x].w){if (tree[v].sum&1^1) In[y]=1,cnt++;cut(e[y].u,y+n);cut(e[y].v,y+n);link(u,x+n);link(v,x+n);on[y]=0;on[x]=1;}elseif (tree[v].sum&1^1) In[x]=1,cnt++;}
}
void del(int x)
{if (on[x]) cut(e[x].u,x+n),cut(e[x].v,x+n);else if (In[x]) cnt--;
}
int main()
{in(n);in(m);int s,t;for (int i=1;i<=n;i++) tree[i].val=tree[i].minn=MAXINT,tree[i].st=i;for (int i=1;i<=m;i++){in(e[i].u);in(e[i].v);s=0;t=i;e[i].w=t;insert1(s,i);insert2(t,i);tree[i+n].val=tree[i+n].minn=t;tree[i+n].st=i+n;tree[i+n].sum=1;e[i+m].u=e[i].u;e[i+m].v=e[i].v;s=i+1;t=m+2;e[i+m].w=t;insert1(s,i+m);insert2(t,i+m);tree[i+m+n].val=tree[i+m+n].minn=t;tree[i+m+n].st=i+m+n;tree[i+m+n].sum=1;}for (int x=0;x<=m+1;x++){for (Edge *i=prev1[x];i;i=i->next) ins(i->to);for (Edge *i=prev2[x];i;i=i->next) del(i->to);if (!cnt) { for (Edge *i=prev2[x];i;i=i->next) ans[++ans[0]]=i->to; }}sort(ans+1,ans+ans[0]+1);printf("%d\n",ans[0]);for (int i=1;i<=ans[0];i++) printf(i==ans[0]?"%d\n":"%d ",ans[i]);
}
【CodeForces19E】Fairy相关推荐
- 【XSY2508】【BZOJ4424】Fairy(二分图)
题面 Description 给定nnn个点,mmm条边的无向图(无自环),可以从图中删除一条边,问删除哪些边可以使图变成一个二分图. Input 第111行包含两个整数nnn,mmm,分别表示点数和 ...
- 【QBXT】学习笔记——Day3/4图论+dp
继续上传一波笔记吧. Day3 1.16AM 今天讲图论,以习题为主. 开篇水题: 给一幅图,若删去一个点后变成一棵树,则这个点合法.问哪些点合法. 思路根据树的性质:这个点不是割点,m-这个点的度数 ...
- 【BZOJ4424】Cf19E Fairy DFS树
[BZOJ4424]Cf19E Fairy Description 给定 n 个点,m 条边的无向图,可以从图中删除一条边,问删除哪些边可以使图变成一个二分图. Input 第 1 行包含两个整数 n ...
- 基于QT(C++)实现(窗体)平台类对战游戏【100010513】
1. 设计任务的描述 用面向对象的设计方法来设计一款平台类对战游戏. 内容包括宠物小精灵的加入.用户注册与平台登录.游戏对战的设计. 2. 功能需求说明及分析 2.1 宠物小精灵的加入 设计宠物小精灵 ...
- 【Keras-MLP】IMDb
文章目录 1 数据处理 1.1 下载解压数据集 1.2 读入数据集 1.3 建立单词数字映射字典 1.4 根据字典把单词换成数字 1.5 使转换后的数字长度相同 2 MLP模型进行IMDb情感分析 2 ...
- 【CentOS】利用Kubeadm部署Kubernetes (K8s)
[CentOS]利用Kubeadm部署Kubernetes (K8s)[阅读时间:约10分钟] 一.概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 三.具体实验流程 1 系统准 ...
- 【Spring】框架简介
[Spring]框架简介 Spring是什么 Spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Asp ...
- 【C#】类——里式转换
类是由面对对象程序设计中产生的,在面向结构的程序设计例如C语言中是没有类这个概念的!C语言中有传值调用和传址调用的两种方式!在c语言中,主方法调用方法,通过传递参数等完成一些操作,其中比较常用的的数据 ...
- 【C#】Out与ref是干什么的?
关于return: 1.最后没有写 return 语句的话,表示程序正常退出 2.不需要返回值时,存在return的作用 例子 void main() {return; //return退出该程序的作 ...
最新文章
- 可以给img元素设置背景图
- 卡尔曼滤波---实例讲解
- ImportError: cannot import name ‘moving_averages‘
- Java微信公众号开发梳理
- 计算机三级上机考试题库,计算机三级数据库上机试题及答案
- MicroBlaze AXI总线 GPIO中断使用(On Atyls Board)
- [渝粤教育] 重庆电子工程职业学院 信息技术与人工智能基础 参考 资料
- 面向对象(Python):学习笔记之多态
- 高中计算机会考vb教程,高中会考计算机vb知识点
- 计算机中word繁体字转简体字,word简繁体怎么转换的两种方法
- 12x12怎么速算_12x12怎么速算_12x12怎样巧算
- 一个碌碌无为的程序员
- gmac网卡驱动1-------mac与phy基础知识
- 学而后思,方能发展;思而立行,终将卓越
- jquery3.2 在线引用地址
- 生信技能9 - 生物信息分析必须掌握的生物学基本概念(建议收藏)
- 浅谈Python类的属性和方法
- 汇编:汇编的基本介绍
- [转载]打工辛酸路:我是一朵飘零的花之22
- vb通过网址下载pdf
热门文章
- 通过硬盘安装linux的方法
- linux php ya ziparchive,linux下zipArchive终于工作了
- plsql登录时没有可选数据库和链接问题
- 【QPSK中频】基于FPGA的QPSK中频信号产生模块verilog设计
- 神经网络理论及应用答案,人工神经网络原理答案
- 波数及波数向量(波矢量)
- 人脸检测数据集评价代码FDDB evaluation运行方法
- 上传文件夹到nas服务器,文件上传到群晖服务器
- BGP in the datacenter, 数据中心的BGP,数据中心网络架构,Clos网络架构
- 电子病历,到底是用BS还是CS