Codeforces.542E.Playing on Graph(二分图)
\(Description\)
给出一个n个点m条边的无向图。
你每次需要选择两个没有边相连的点,将它们合并为一个新点,直到这张图变成了一条链。
最大化这条链的长度,或输出无解。
n<=1000,m<=10000
\(Solution\)
不难发现无解当且仅当存在奇环。
归纳证明:有一个奇环,若与环外一个点合并,这个奇环仍存在;若环内两个点合并,合并两点两边的边数是奇数,合并之后还是至少会有一边边数是奇数,是一个奇环(最后变成一个三角形)。这样怎么合并都会剩下一个奇环。
若不存在奇环,则这是一张二分图(一定有解,直接左右分别合成一定可以形成一个长度为2的链)。
先考虑一些特殊情况
对于一棵树显然答案是直径,然后挂在直径边的点直接合并上去。
对于一个偶环,则找的是对称的两个点,答案应是n/2+1.

树是因为两点间的距离固定,所以找一个最长的;
而环是找了最短路最长的一对点。
假设一个点对(a,b)的最短路为x,缩点(相等于添边)x只会变短,那么合并完 (a,b)的距离y一定<=x。这相当于找到一个ans的上界,想办法把答案构出来。
考虑枚举一个点作为链的一端,求出其它点到它的距离di。
因为是个二分图,所以距离某个点距离相等的点一定在二分图的同一侧。
直接把di相同的点合到一起就可以了,会得到一条长度为max{di}的链,并且肯定不存在更长的链。
时间复杂度O(nm)(BFS是必须的 用DFS求最终答案是错的!)
注: 若图不是连通的,则ans=D1+D2+…+Dk(Di为每个连通块的max{di})
//1980ms 3600KB 好慢啊。。
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define gc() getchar()
const int N=1e3+5,M=1e5+5;
int n,m,Enum,H[N],nxt[M<<1],to[M<<1],vis[N],cnt,bel[N],ans_b[N],dis[N],q[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v){
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS(int x,int f)
{
bel[x]=cnt;
for(int v,i=H[x]; i; i=nxt[i])
if((v=to[i])!=f && !vis[v]) vis[v]=vis[x]^1, DFS(v,x);
else if(/*v!=f*/vis[v]==vis[x]) {printf("-1"); exit(0);}
}
int BFS(int now)
{
memset(dis,0,sizeof dis);
int h=0,t=1,res=0; q[0]=now, dis[now]=1;
while(h<t)
{
int x=q[h++];
for(int i=H[x]; i; i=nxt[i])
if(!dis[to[i]])
res=std::max(res,dis[to[i]]=dis[x]+1),q[t++]=to[i];
}
return res-1;
}
int main()
{
n=read(),m=read();
for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),AddEdge(u,v);
for(int i=1; i<=n; ++i)
if(!vis[i]) ++cnt,vis[i]=2,DFS(i,i);
for(int i=1; i<=n; ++i)
ans_b[bel[i]]=std::max(ans_b[bel[i]],BFS(i));
int res=0;
for(int i=1; i<=cnt; ++i) res+=ans_b[i];
printf("%d",res);
return 0;
}
Codeforces.542E.Playing on Graph(二分图)的更多相关文章
- Codeforces 542E Playing on Graph 其他
原文链接https://www.cnblogs.com/zhouzhendong/p/CF542E.html 题目传送门 - CF542E 题目传送门 - 51Nod1481 题意 有一幅无向图,它有 ...
- cf 542E - Playing on Graph
cf 542E - Playing on Graph 题目大意 给定一个\(n\le 1000\)个点的图 求经过一系列收缩操作后能否得到一条链,以及能得到的最长链是多长 收缩操作: 选择两个不直接相 ...
- Codeforces 459E Pashmak and Graph(dp+贪婪)
题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边依 ...
- 【Codeforces542E】Playing on Graph [Bfs][Dfs]
Playing on Graph Time Limit: 20 Sec Memory Limit: 512 MB Description Input Output Sample Input 5 4 ...
- ACM - 最短路 - CodeForces 295B Greg and Graph
CodeForces 295B Greg and Graph 题解 \(Floyd\) 算法是一种基于动态规划的算法,以此题为例介绍最短路算法中的 \(Floyd\) 算法. 我们考虑给定一个图,要找 ...
- CodeForces - 1093D:Beautiful Graph(二分图判定+方案数)
题意:给定无向图,让你给点加权(1,2,3),使得每条边是两端点点权和维奇数. 思路:一个连通块是个二分图,判定二分图可以dfs,并查集,2-sat染色. 这里用的并查集(还可以带权并查集优化一下,或 ...
- Educational Codeforces Round 56 (Rated for Div. 2) D. Beautiful Graph (二分图染色)
题意:有\(n\)个点,\(m\)条边的无向图,可以给每个点赋点权\({1,2,3}\),使得每个点连的奇偶不同,问有多少种方案,答案对\(998244353\)取模. 题解:要使得每个点所连的奇偶不 ...
- POJ 2125 Destroying the Graph 二分图最小点权覆盖
Destroying The Graph Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8198 Accepted: 2 ...
- CodeForces 176C Playing with Superglue 博弈论
Playing with Superglue 题目连接: http://codeforces.com/problemset/problem/176/C Description Two players ...
随机推荐
- 用C#代码来安装、卸载、启动、关闭服务
/// <summary> /// 启动服务 /// </summary> /// <param name="sen ...
- 003_饿了么chaosmonkey实现
背景 公司目前的服务设计大部分满足 design for failure 理念.随着业务复杂度的提升,我们很难再保证对系统故障的容错性.我们需要工具来验证服务的容错性,基于这个需求我们使用了 tc 工 ...
- GitHub学习一-本地电脑与GitHub绑定
1.创建ssh key $ ssh-keygen -t rsa -C "your_email@youremail.com"安装完git,右键git bash here,创建ssh ...
- Python-HTML基础
1.HTML 1.HTML是什么 超文本标记语言,即学习这门语言就是在一堆标记 2.为何要用? 标记文本 3.如何用? HTML标签就是用来做记号的,虽然这些记号自带一些样式,但务必忽略掉记号的样式, ...
- PYTHON-模块-time&datetime-练习 +目录规范
# 作业# 1.请写出规范目录# 并解释各文件夹的作用bin 可执行文件conf 配置文件core 主要业务逻辑db 数据文件lib 库(公共代码 第三方模块)log 日志文件 # 2.改造atm + ...
- 如何从现有版本升级到element UI2.0?使用npm-check-updates
转:https://blog.csdn.net/wojiaomaxiaoqi/article/details/78428738 登录element UI官网时提示2.0已经正式发布了,Element ...
- Git 将项目(代码)从GitHub上克隆(下载)到本地仓库
要将项目从GitHub上克隆到本地,首先你得下载并安装好git for window. 配置Git: 1.安装完后,右键单击桌面空白处,选择Git Gui Here,进去之后,选择左上角的help选项 ...
- jquery----用户密码验证
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Splay-Tree总结一:模拟队列
伸展树是一种强大的数据结构,由于其特性,可以很好地模拟队列的插队等操作,而线段树解决这类问题通常需要转化一下,比较伤脑筋 而用伸展树的解决方法就是先建好一颗节点数等于队列长度的树,每个队列元素在队列中 ...
- python 全栈开发,Day79(Django的用户认证组件,分页器)
一.Django的用户认证组件 用户认证 auth模块 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中: 如果用户存在于数据库中,然后再验证用户 ...
