cf 542E - Playing on Graph

题目大意

给定一个\(n\le 1000\)个点的图

求经过一系列收缩操作后能否得到一条链,以及能得到的最长链是多长

收缩操作:

选择两个不直接相连的点,构造一个新点

对于原图中的每一个点,如果它与这两个点中的任意一个有连边

那么它向这个新点连一条边

最后删除选择的两个点,以及所有这两个点的连边

分析

注意到对于一个奇环,无论怎么收缩,都会产生一个新的奇环,最后奇环变成一个三角形,再也缩不了,永远无法变成一条链

只有偶环的图是二分图

对于图中的一个子图,它是二分图,我们就能构造一组解

选择一个点作为起点,从该点出发得到一棵\(bfs\)树

由于是二分图,\(bfs\)树同一层节点之间没有连边

由于是\(bfs\)树,每个点的连边只能在相邻一层的范围内,且必定和上一层节点有连边

那么我们把同一层节点缩在一起,就可以得到一条链

按照这种方法,图的直径就是答案(图的直径为最短路中的最大值

直径时最优解可以用归纳法证明:

对于\(1\)个点的任意图显然成立

假设对于\(n\)个点的任意图成立,那么对于\(n+1\)个点的任意图

如果图中不存在环,那么是一棵树,直径显然是答案

否则,至少进行一次收缩,则答案为缩掉一对点后的直径中最大是多少

缩掉一个点后的直径一定不比原来的直径大

而原来的直径能构造出一组解

连通块间的答案是相加的:

对于图中的所有联通块,每块缩成一条链后,链可以两两合并

做法

先判断是不是二分图

然后每个联通块求一次图的直径

然后所有联通块的答案加起来

图的直径求法是每个点出发跑一次\(bfs\)

solution

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int M=1007;
const int N=1e5+7; inline int ri(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
} int n,m; struct vec{
int g[M],te;
struct edge{
int y,nxt;
edge(int _y=0,int _nxt=0){y=_y,nxt=_nxt;}
}e[N<<1];
vec(){memset(g,0,sizeof g);te=0;}
inline void push(int x,int y){e[++te]=edge(y,g[x]);g[x]=te;}
inline void push2(int x,int y){push(x,y);push(y,x);}
inline int& operator () (int x){return g[x];}
inline edge& operator [] (int x){return e[x];}
}e; int vis[M],ok,ans;
vector<int>pt;
int d[M]; void dfs(int x){
int p,y;
for(p=e(x);p;p=e[p].nxt){
y=e[p].y;
if(!vis[y]){
vis[y]=3-vis[x];//1->2 2->1
dfs(y);
}
else if(vis[y]!=3-vis[x]) ok=0;
}
} bool chk(){
ok=1;
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
if(!vis[i]) vis[i]=1,dfs(i);
return ok;
} int gao(int bg){
static int q[M];
int h=0,t=1,x,p,y,i,mx=0;
for(i=0;i<pt.size();i++) d[pt[i]]=-1;
q[1]=bg;d[bg]=0;
while(h!=t){
x=q[++h];
mx=max(mx,d[x]);
for(p=e(x);p;p=e[p].nxt)
if(d[y=e[p].y]==-1){
d[y]=d[x]+1;
q[++t]=y;
}
}
return mx;
} void getpt(int x){
vis[x]=1; pt.push_back(x);
for(int p=e(x);p;p=e[p].nxt) if(!vis[e[p].y]) getpt(e[p].y);
} int chain(int x){
int i,mx=0; pt.clear();
getpt(x);
for(i=0;i<pt.size();i++) mx=max(mx,gao(pt[i]));
return mx;
} void solve(){
ans=0;
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
if(!vis[i]) ans+=chain(i);
printf("%d\n",ans);
} int main(){ int i; n=ri(),m=ri(); for(i=1;i<=m;i++) e.push2(ri(),ri()); if(chk()) solve();
else puts("-1"); return 0;
}

cf 542E - Playing on Graph的更多相关文章

  1. Codeforces 542E Playing on Graph 其他

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF542E.html 题目传送门 - CF542E 题目传送门 - 51Nod1481 题意 有一幅无向图,它有 ...

  2. Codeforces.542E.Playing on Graph(二分图)

    题目链接 \(Description\) 给出一个n个点m条边的无向图. 你每次需要选择两个没有边相连的点,将它们合并为一个新点,直到这张图变成了一条链. 最大化这条链的长度,或输出无解. n< ...

  3. 【Codeforces542E】Playing on Graph [Bfs][Dfs]

    Playing on Graph Time Limit: 20 Sec  Memory Limit: 512 MB Description Input Output Sample Input 5 4 ...

  4. Codeforces542E Playing on Graph 思维+DFS+BFS

    解法参考https://www.cnblogs.com/BearChild/p/7683114.html这位大佬的,这位大佬讲得很好了. 这道题还是有一定的思维的. 直接贴代码: #include&l ...

  5. Codeforces刷题计划

    Codeforces刷题计划 已完成:-- / -- [Codeforces370E]370E - Summer Reading:构造:(给定某些数,在空白处填数,要求不下降,并且相邻差值<=1 ...

  6. CF Playing with Paper

    Playing with Paper time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. CF 329C(Graph Reconstruction-随机化求解-random_shuffle(a+1,a+1+n))

    C. Graph Reconstruction time limit per test 3 seconds memory limit per test 256 megabytes input stan ...

  8. CF 724 G. Xor-matic Number of the Graph

    G. Xor-matic Number of the Graph 链接 题意: 给定一个无向图,一个interesting的三元环(u,v,s)满足,从u到v的路径上的异或和等于s,三元环的权值为s, ...

  9. cf 251 B Playing with Permutations 暴力 分类讨论

    题链;http://codeforces.com/problemset/problem/251/B B. Playing with Permutations time limit per test 2 ...

随机推荐

  1. POJ 2774 后缀数组 || 二分+哈希

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 35607   Accepted: 14 ...

  2. linux 下nginx除了首页404的问题

    今天在部署tp5的时候除了首页能访问.其他都是not found 原因是 Nginx服务器默认不支持pathinfo,index.php后面的参数都没带上   在需要pathinfo支持的程序中 则无 ...

  3. 该网页无法正常运作 目前无法处理此请求HTTP ERROR 500?

    由于php.ini配置文件中错误显示关闭导致. 将下值由Off 变更为 On display_errors = On display_startup_errors = On

  4. python中生成器对象和return 还有循环的区别

    python中生成器对象和return 还有循环的区别 在python中存在这么一个关键字yield,这个关键字在项目中经常被用到,比如我写一个函数不想它只返回一次就结束那我们就不能用return,因 ...

  5. 问题 B: 分组统计

    分组统计 问题 B: 分组统计时间限制: 1 Sec 内存限制: 32 MB 提交: 416 解决: 107 [提交][状态][讨论版][命题人:外部导入] 题目描述 先输入一组数,然后输入其分组,按 ...

  6. RDLC Reporting in Visual Studio 2017

    原文:RDLC Reporting in Visual Studio 2017 Visual Studio 2017 中可以使用 RDLC Reporting 插件来设计报表,SAP Crystal ...

  7. [原]sencha touch之carousel

    carousel组件是个非常不错的东东,自带可滑动的效果,效果如下图 上面部分可以左右滑动,下面部分可以上下滑动,效果还是不错的,app程序中很有用的布局 代码如下: Ext.application( ...

  8. TCP/IP网络编程之基于TCP的服务端/客户端(二)

    回声客户端问题 上一章TCP/IP网络编程之基于TCP的服务端/客户端(一)中,我们解释了回声客户端所存在的问题,那么单单是客户端的问题,服务端没有任何问题?是的,服务端没有问题,现在先让我们回顾下服 ...

  9. mysql插入、修改、删除

    联合查询: union:合并.联合,将多次查询结果合并成一个结果 语法: 查询语句1: union[all] 查询语句2: union [all] ... 意义 1.将一条比较复杂的查询语句可拆分成多 ...

  10. C#入门篇6-1:字符串操作 char常用的函数

    //char 字符的常见操作 public static void FChar() { //判定字符的类别 char ch1 = 'a';//使用小引号 bool bl = true; bl = ch ...