[Solution] JZOJ-5806 简单的操作
[Solution] JZOJ-5806 简单的操作
题面
Description
从前有个包含n个点,m条边,无自环和重边的无向图。
对于两个没有直接连边的点u;v,你可以将它们合并。具体来说,你可以删除u;v及所有以它们作为端点的边,然后加入一个新点x,将它与所有在原图中与u或v有直接连边的点连边。
你需要判断是否能通过若干次合并操作使得原图成为一条链,如果能,你还需要求出这条链的最大长度
Input
从文件merge.in中读入数据。
第一行两个正整数n;m,表示图的点数和边数。
接下来m行,每行两个正整数u;v,表示u和v之间有一条无向边
Output
输出到文件merge.out中。
如果能通过若干次合并操作使得原图成为一条链,输出链的最大长度,否则输出-1
Sample Input
【样例1输入】
5 4
1 2
2 3
3 4
3 5
【样例2输入】
4 6
1 2
2 3
1 3
3 4
2 4
1 4
Sample Output
【样例1输出】
3
【样例2输出】
-1
Data Constraint
对于30%的数据, n<=10
对于70%的数据, m<=2000
对于100%的数据, n<=1000,m<=1e5
分割线
解题思路
经过手动模拟,可以发现:当这个图中存在奇环的时候必然无解:因为三元环是肯定无解的(脚动模拟,不解释),所有的奇数元环都可以经过变换成为三元环,因此无解。
重点
不存在奇环的图是二分图(定义,自己去搜),因此搜一遍判二分图可以直接搜出无解的情况输出-1并返回
经过脚动模拟可以发现:每个联通块都可以缩成一条链,链长就是任意两点之间最短路的最大值。
我们继续经过脚动模拟可以发现:任意两个联通块之间相连得到的最大链长就是分别的最大链长之和
然后使用BFS搜一下每个联通块里的最短路中的最大值,然后累加就OK了
具体见Code
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#define ll long long
#define inf 0x3f3f3f3f
#define maxn 1005
using namespace std;
int n,m;
struct Edge{
int t,nxt;
}edge[maxn*200];
int head[maxn],tot=0;
int fa[maxn];
int rot[maxn];
int len[maxn];
int book[maxn];
queue<int> q;
int gf(int x){return x==fa[x]?x:fa[x]=gf(fa[x]);}
void add(int st,int to){edge[tot].t=to;edge[tot].nxt=head[st];head[st]=tot;tot++;}
int gmax(int a,int b){return a>b?a:b;}
int check(int s){
memset(book,-1,sizeof(book));
while(q.size()) q.pop();
book[s]=1;
q.push(s);
while(!q.empty()){
int ni=q.front();
q.pop();
for(int i=head[ni];i!=-1;i=edge[i].nxt){
int nt=edge[i].t;
if(book[nt]==-1){
book[nt]=1-book[ni];
q.push(nt);continue;
}
else{
if(book[nt]+book[ni]!=1)
return 0;
}
}
}
return 1;
}
int sp(int s){
while(q.size()) q.pop();
memset(book,-1,sizeof(book));
int ans=0;
book[s]=0;
q.push(s);
while(!q.empty()){
int ni=q.front();
q.pop();ans=gmax(ans,book[ni]);
for(int i=head[ni];i!=-1;i=edge[i].nxt){
int nt=edge[i].t;
if(book[nt]==-1){
book[nt]=book[ni]+1;
q.push(nt);
}
}
}
return ans;
}
int solve(int f){
int ans=-1;
for(int i=1;i<=n;i++)
if(gf(i)==f)
ans=gmax(ans,sp(i));
return ans;
}
int main(){
freopen("merge.in","r",stdin);
freopen("merge.out","w",stdout);
memset(head,-1,sizeof(head));
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
int a,b;scanf("%d %d",&a,&b);
add(a,b);add(b,a);
if(gf(a)!=gf(b))
fa[gf(a)]=gf(b);
}
tot=0;
for(int i=1;i<=n;i++)
if(gf(i)==i){
rot[tot]=i;
tot++;
}
for(int i=0;i<tot;i++)
if(check(rot[i])==0){
printf("-1\n");return 0;
}
int ans=0;
for(int i=0;i<tot;i++)
ans+=solve(rot[i]);
printf("%d\n",ans);
return 0;
}
[Solution] JZOJ-5806 简单的操作的更多相关文章
- salesforce 零基础开发入门学习(三)sObject简单介绍以及简单DML操作(SOQL)
salesforce中对于数据库操作和JAVA等语言对于数据库操作是有一定区别的.salesforce中的数据库使用的是Force.com 平台的数据库,数据表一行数据可以理解成一个sObject变量 ...
- 下面介绍一下 Yii2.0 对数据库 查询的一些简单的操作
下面介绍一下 Yii2.0 对数据库 查询的一些简单的操作 User::find()->all(); 此方法返回所有数据: User::findOne($id); 此方法返回 主键 id=1 的 ...
- SequoiaDB 系列之二 :SequoiaDB的简单CRUD操作
上一篇通过一系列的操作,终于把SequoiaDB的集群部署到单台机器上了. 建议去安装体验一下吧. 在整个环境的部署的体验来看,并没有MongoDB的部署简单,但是比MongoDB的部署要清晰.Mon ...
- js实用方法记录-简单cookie操作
js实用方法记录-简单cookie操作 设置cookie:setCookie(名称,值,保存时间,保存域); 获取cookie:setCookie(名称); 移除cookie:setCookie(名称 ...
- ado.net的简单数据库操作(一)
摘要:接下来的几篇博客将要讲到如何使用ado.net实现简单的数据库操作,包括增删改等内容.首先会介绍基础的数据库操作,然后以一个实例来进行讲解,这个实例会把一个数据表读取到winform上,然后在w ...
- selenium--控制浏览器和简单元素操作
控制浏览器1.driver.maximize_window() #浏览器最大化2.driver.set_windows_size(480*800) #浏览器设置成移动端大小(480*800),参数数字 ...
- [solution] JZOJ 5459. 密室
[solution] JZOJ 5459. 密室 Description 小X 正困在一个密室里,他希望尽快逃出密室. 密室中有$N$ 个房间,初始时,小X 在1 号房间,而出口在N 号房间. 密室的 ...
- Solr可视化简单的操作
Solr可视化简单的操作 启动solr服务器;在浏览器输入Tomcat启动: http://192.168.191.142:8080/solr/#/ Ø 添加core,首先在存放home的文件下创建 ...
- SqlServer简单的操作XML以及SQl的 try catch等统一格式
1:SqlServer简单的操作XML: ALTER PROCEDURE [dbo].[SP_CRM_FranchiseeRecharge_Money] @Create_By VARCHAR(), @ ...
随机推荐
- POJ1003 – Hangover (基础)
Hangover Description How far can you make a stack of cards overhang a table? If you have one card, ...
- [NOI2011]智能车比赛 (计算几何 DAG)
/* 可以发现, 最优路径上的所有拐点, 基本上都满足一定的性质, 也就是说是在矩形上的拐角处 所以我们可以把他们提出来, 单独判断即可 由于我们提出来的不超过2n + 2个点, 我们将其按照x坐标排 ...
- vue中.sync 修饰符
一直以来,都不太明白.sync的用法,归根结底原因在于,没有仔细阅读“.sync修饰符”. 正好,最近在拿一个项目练手,然后使用了elment-ui,然后在用到dialog的时候,属性visible是 ...
- C++ #define #if #ifndef 宏指令
不会用就直接复制粘贴 #define CURSOR(top,bottom) (((top)<<8)|(bottom)) #define mul(x1,x2) (x1*x2) #define ...
- 学习excel的使用技巧四显示正常的数字
记得之前在excel中输入一些数字比如输入手机号 就会变成1.E几类似这种 那么怎样显示正常的数字呢 先选中要操作的输入框 1 找到 数字 这个功能的地方 2 设置为 数值 并且小数点为0 3 ...
- python:选房抽签小工具
1.房间号和姓名写在house_name.xls的house标签页中[注意!名字均不要改动]2.运行house.py3.当前同目录下会生成result.xls,即为结果:程序运行过程中不要打开该文件, ...
- ZigBee相关网站链接
1.Arduino开源智能家居<认识Zigbee>zigbee功能和自组网介绍-Arduino中文社区 2.小米智能家庭套装为什么选择 ZigBee 协议?|极客公园 3.晓网智能家居Zi ...
- Windows Server 2008中使用计划任务定时执行BAT bat进行PHP脚本的执行
Windows Server 2008中使用计划任务定时执行BAT bat进行PHP脚本的执行 2016年01月03日 17:36:00 持之以恒 阅读数:5520 标签: windows定时任务.b ...
- Docker 简介,入门
1.简介 Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行 ...
- 最长子序列dp poj2479 题解
Maximum sum Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 44476 Accepted: 13796 Des ...