cf 542E - Playing on Graph

题目大意

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

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

收缩操作:

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

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

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

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

分析

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

只有偶环的图是二分图

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

做法

先判断是不是二分图

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

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

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

solution

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cctype>
  5. #include <cmath>
  6. #include <algorithm>
  7. #include <vector>
  8. using namespace std;
  9. const int M=1007;
  10. const int N=1e5+7;
  11. inline int ri(){
  12. int x=0;bool f=1;char c=getchar();
  13. for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
  14. for(;isdigit(c);c=getchar()) x=x*10+c-48;
  15. return f?x:-x;
  16. }
  17. int n,m;
  18. struct vec{
  19. int g[M],te;
  20. struct edge{
  21. int y,nxt;
  22. edge(int _y=0,int _nxt=0){y=_y,nxt=_nxt;}
  23. }e[N<<1];
  24. vec(){memset(g,0,sizeof g);te=0;}
  25. inline void push(int x,int y){e[++te]=edge(y,g[x]);g[x]=te;}
  26. inline void push2(int x,int y){push(x,y);push(y,x);}
  27. inline int& operator () (int x){return g[x];}
  28. inline edge& operator [] (int x){return e[x];}
  29. }e;
  30. int vis[M],ok,ans;
  31. vector<int>pt;
  32. int d[M];
  33. void dfs(int x){
  34. int p,y;
  35. for(p=e(x);p;p=e[p].nxt){
  36. y=e[p].y;
  37. if(!vis[y]){
  38. vis[y]=3-vis[x];//1->2 2->1
  39. dfs(y);
  40. }
  41. else if(vis[y]!=3-vis[x]) ok=0;
  42. }
  43. }
  44. bool chk(){
  45. ok=1;
  46. memset(vis,0,sizeof vis);
  47. for(int i=1;i<=n;i++)
  48. if(!vis[i]) vis[i]=1,dfs(i);
  49. return ok;
  50. }
  51. int gao(int bg){
  52. static int q[M];
  53. int h=0,t=1,x,p,y,i,mx=0;
  54. for(i=0;i<pt.size();i++) d[pt[i]]=-1;
  55. q[1]=bg;d[bg]=0;
  56. while(h!=t){
  57. x=q[++h];
  58. mx=max(mx,d[x]);
  59. for(p=e(x);p;p=e[p].nxt)
  60. if(d[y=e[p].y]==-1){
  61. d[y]=d[x]+1;
  62. q[++t]=y;
  63. }
  64. }
  65. return mx;
  66. }
  67. void getpt(int x){
  68. vis[x]=1; pt.push_back(x);
  69. for(int p=e(x);p;p=e[p].nxt) if(!vis[e[p].y]) getpt(e[p].y);
  70. }
  71. int chain(int x){
  72. int i,mx=0; pt.clear();
  73. getpt(x);
  74. for(i=0;i<pt.size();i++) mx=max(mx,gao(pt[i]));
  75. return mx;
  76. }
  77. void solve(){
  78. ans=0;
  79. memset(vis,0,sizeof vis);
  80. for(int i=1;i<=n;i++)
  81. if(!vis[i]) ans+=chain(i);
  82. printf("%d\n",ans);
  83. }
  84. int main(){
  85. int i;
  86. n=ri(),m=ri();
  87. for(i=1;i<=m;i++) e.push2(ri(),ri());
  88. if(chk()) solve();
  89. else puts("-1");
  90. return 0;
  91. }

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. 1037: [ZJOI2008]生日聚会Party

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3121  Solved: 1858[Submit][Status][Discuss] Descript ...

  2. Spring+ ApplicationListener

    有时候 需要在容器初始化完成后,加载些 代码字典或不常变的信息  放入缓存之类的,这里使用spring 初始化bean,并实例化 1.创建一个ApplicationListener类 import o ...

  3. 项目实战14.1—ELK 企业内部日志分析系统

    本文收录在Linux运维企业架构实战系列 一.els.elk 的介绍 1.els,elk els:ElasticSearch,Logstash,Kibana,Beats elk:ElasticSear ...

  4. nginx+django线上部署

    (一):背景在线 由于现在工作的需要,我需要使用Python来进行一个网站后台的开发,python之前接触过其语法的学习,基本的东西已经掌握,但是当时自学的时候是学得python3.5,而现在要使用p ...

  5. JZOJ 5838. 旅游路线 最大子段和

    5838. 旅游路线 Time Limits: 1000 ms  Memory Limits: 131072 KB  Detailed Limits   Goto ProblemSet Descrip ...

  6. spark和MR比较

    MapReduce: 分布式的计算框架 缺点:执行速度慢 IO瓶颈 ==> 磁盘IO 网络IO shuffle机制:数据需要输出到磁盘,而且每次shuffle都需要进行排序操作 框架的机制: 只 ...

  7. Android四大基本组件介绍及生命周期

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一.了解四大基本组件 Activity ...

  8. Android四大组件之服务

    创建一个服务,并与活动绑定 作为安卓四大组件之一的服务,毫无例外也要在manifast中进行注册 新建服务类继承于Service,并覆盖onBind( )方法,用于与活动绑定 public class ...

  9. hashlib加密模块

    python hashlib密码加密   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/dss_dssssd/article/details/828 ...

  10. Apache Common-IO 使用

    Apache Common-IO 是什么? Apache File 工具类,能够方便的操作 File 运行环境 jdk 1.7 commons-io 2.6 测试代码 package com.m.ba ...