bzoj2841
边双联通分量
具体详解蓝书上十分详细,因为必须是奇数个人坐在一起,那么一个人如果能选上,就必须处在一个简单奇圈中。而奇圈也是一个边双联通分量,所以我们先把边双联通分量都挖出来,然后进行二分图染色。
奇圈不能被二分图染色,所以标记所有不能被染色的点,减去就是答案
#include<bits/stdc++.h>
using namespace std;
const int N = ;
int n, top, cnt, tot, color, ans, m;
int dfn[N], low[N], st[N], vis[N], col[N], mark[N], head[N];
struct edge {
int nxt, to;
} e[N << ];
vector<int> G[N];
void link(int u, int v)
{
e[++cnt].nxt = head[u];
head[u] = cnt;
e[cnt].to = v;
}
void tarjan(int u, int last)
{
dfn[u] = low[u] = ++tot; st[++top] = u;
for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last)
{
if(!dfn[e[i].to])
tarjan(e[i].to, u);
if(dfn[e[i].to] != -)
low[u] = min(low[u], low[e[i].to]);
}
if(low[u] == dfn[u])
{
++color;
while(st[top + ] != u)
{
dfn[st[top]] = -;
col[st[top]] = color;
--top;
}
}
}
bool dfs(int u, int c)
{
vis[u] = c;
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(vis[v] == c) return false;
if(!vis[v])
if(!dfs(v, c ^ ))
return false;
}
return true;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= m; ++i)
{
int u, v; scanf("%d%d", &u, &v);
link(u, v);
link(v, u);
}
for(int i = ; i <= n; ++i)
if(!dfn[i])
tarjan(i, );
for(int i = ; i <= n; ++i)
for(int j = head[i]; j; j = e[j].nxt)
if(col[e[j].to] == col[i])
{
G[e[j].to].push_back(i);
G[i].push_back(e[j].to);
}
memset(vis, -, sizeof(vis));
for(int i = ; i <= n; ++i)
if(vis[i] == - && !dfs(i, ))
mark[col[i]] = ;
ans = n;
for(int i = ; i <= n; ++i)
if(mark[col[i]])
--ans;
printf("%d\n", ans);
return ;
}
bzoj2841的更多相关文章
随机推荐
- 使用SELECT语句检索数据
使用SELECT语句检索数据select指令适用于SQL数据库SELECT 语句用于从数据库中选取数据.(指令不分大小写,选择的值除名字和一些有特殊意义的字符可不分大小写,from结束时一定要加;) ...
- layer iframe层弹出图片
这个js是在一个layer iframe弹出层中,点击按钮弹出图片
- JAVA基础——文件File简单实用
1.1java.io.File File用于表示文件系统中的一个文件或目录 通过File可以: 1:访问该文件或目录的属性信息(名字,大小,修改时间等) file.getName();获取文件名fil ...
- 第二章 设计高质量的React组件
第二章 设计高质量的React组件 高质量React组件的原则和方法: 划分组件边界的原则: React组件的数据种类: React组件的生命周期. 2.1 易于维护组件的设计要素 1.高内聚:指的是 ...
- 洛谷——P3275 [SCOI2011]糖果
P3275 [SCOI2011]糖果 差分约束模板题,基本思路就是$d[v]+w[v,u]<=d[u]$,$Spfa$更新方法, 有点套路的是要建立原点,即图中不存在的点来向每个点加边,但同样这 ...
- UVA-12333 Revenge of Fibonacci(竖式加法模拟 & 字典树)
题目: 给出一个斐波那契数字的前缀,问第一个有这个前缀的数字在斐波那契数列中是第几个. 思路: 紫书提示:本题有一定效率要求.如果高精度代码比较慢,可能会超时. 利用滚动数组和竖式加法来模拟斐波那契相 ...
- Springboot源码分析
参考资料 https://www.cnblogs.com/lizongshen/p/9127999.html
- 小数化分数的O(log2n)解法
具体约束: 给定一个小数x,x满足0<=x<1,且保证给定的x保留了18位小数 输出一个分数,使得分母不超过1e9,分子分母互质,且在满足这些条件的情况下最接近x 了解一下法雷数列和ste ...
- PHP小白学习日程之旅
我是一名专升本的学生,在这里偶然接触了博客园,我觉得非常好,每天可以在这里看别人的分享与学习,还会在大学学习俩年,我只想专注的吧自己的技术提高,跟园子里的朋友们一起学习与分享加油!!!!!!!!!!! ...
- Linux下Ubuntu 操作系统 部署
1.1 先更新系统 环境 更新命令为: apt-get update 1.2 安装jdk 安装JDK命令为:sudo apt-get install o penjdk-7-jdk 1.3 安装tomc ...