题目描述

一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会。今年的面具都是主办方特别定制的。每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具。每个面具都有一个编号,主办方会把此编号告诉拿该面具的人。为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特殊的技术将每个面具的编号标在了面具上,只有戴第i 类面具的人才能看到戴第i+1 类面具的人的编号,戴第k 类面具的人能看到戴第1 类面具的人的编号。 参加舞会的人并不知道有多少类面具,但是栋栋对此却特别好奇,他想自己算出有多少类面具,于是他开始在人群中收集信息。 栋栋收集的信息都是戴第几号面具的人看到了第几号面具的编号。如戴第2号面具的人看到了第5 号面具的编号。栋栋自己也会看到一些编号,他也会根据自己的面具编号把信息补充进去。由于并不是每个人都能记住自己所看到的全部编号,因此,栋栋收集的信 息不能保证其完整性。现在请你计算,按照栋栋目前得到的信息,至多和至少有多少类面具。由于主办方已经声明了k≥3,所以你必须将这条信息也考虑进去。

输入

第一行包含两个整数n, m,用一个空格分隔,n 表示主办方总共准备了多少个面具,m 表示栋栋收集了多少条信息。接下来m 行,每行为两个用空格分开的整数a, b,表示戴第a 号面具的人看到了第b 号面具的编号。相同的数对a, b 在输入文件中可能出现多次。

输出

包含两个数,第一个数为最大可能的面具类数,第二个数为最小可能的面具类数。如果无法将所有的面具分为至少3 类,使得这些信息都满足,则认为栋栋收集的信息有错误,输出两个-1。

样例输入

【输入样例一】

6 5
1 2
2 3
3 4
4 1
3 5 【输入样例二】 3 3
1 2
2 1
2 3

样例输出

【输出样例一】
4 4 【输出样例二】
-1 -1

提示

100%的数据,满足n ≤ 100000, m ≤ 1000000。

题解

    今天的四道题除了第二题之外都是以点、边的图论形式给出的,但是并没有用图论的最短路、LCA之类的板子,所以大概算是伪图论。思维量比较大,所谓的一到集训必定做好题;上午灌了不少咖啡所以没有假期刚过的混沌,精神也很集中。考前莫名有点紧张?是到了该重视考试的时候了。ad爷讲题非常棒!比平常上课收获更多,虽然速度快但是理解得比平时深刻。有了强烈的想学学高深数学的想法,自己现在虽然纯代码的东西也不是很强,但是毕竟数学方面最弱,数据结构也不行。好好努力,这几天的集训大概会有所提高吧。ad爷居然说改这些题只需要两个小时,有点不可想象,果然我还是太弱了QAQ。
    考试时打的是并查集,得了10分。从样例就可以看出来判环是一个很重要的步骤,想了想方法大概除了spfa判入队次数就是搜索了,明显不是个最短路的题所以非搜索莫属。题目中总是有一些很让人搞不明白的表述,比如说信息不完整,比如说自己也会看到,比如说不完全覆盖,这种时候就需要自己开动脑筋揣摩一下了。对于环的情况,当时以为搞出环来就算确定了,没有想到最大公约数,虽然偶然中画出了假环的情况但是也没有给出合理的解决办法;对于链的情况,刚开始以为最小只不过是总点数-1,后来想到了3总是可行的,但是到了改题改了很久之后才明白最大应该是链长之和而不是简单的n。总的来说,这道题无论是考还是改都是一步步拓宽思路的过程,开始的思维还是太简单、不够缜密,总是在偶然中擦过了正解的边却还是不能把它推广到真正正确。
真环 1->2->3->4->1 假环 1->2->4->7->6 + 1->3->5->6
直链 1->2->3->4->5 分支型支链 1->2->3->4->5 + 1->2->6
合并型支链 1->2->3->4->5 + 6->7->8->9->3(最后把我困住的一种。选主链,称某烷!)
正解是头插法加边,真边为1假边为-1,用并查集统计联通块,然后对每个联通块dfs,给每个点的标号是父节点标号加边权。如果dfs到一个已经走过的点,比较将要给它的标号和它已有的标号就会得出环的大小(要注意如果将要给它的标号和已有标号一样的话只是说明又回到了这一层,不用作环处理)。如果没有环,每一个链的长度就是出现过的最大标号与最小标号之差+1(这一点我居然一直没想到!各种局部变量各种传参打得乱七八糟还得不出正确答案,最后还是问了zzh才得知“还有这种操作?”)。
void dfs(int x,int fx)
{
vi[x]=1;
int jk;
for(int i=h[x];i!=-1;i=b[i].ne)
{
jk=b[i].v;
if(vi[jk]&&c[x]+b[i].w!=c[jk])
{
if(ans==-1) ans=abs(c[x]+b[i].w-c[jk]);
else ans=gcd(ans,abs(c[x]+b[i].w-c[jk]));
yh=1;
}
c[jk]=c[x]+b[i].w;
bj(zh,c[jk]);
xbj(fh,c[jk]);
if(!vi[jk])
dfs(jk,b[i].w);
}
}
结果:
有环:max=gcd(各环长)
max<3 无解
max>=3 mix=max大于等于3的最小因数
无环:max=各链长之和
max<3 无解
max>=3 mix=3
改题的过程旷日持久,主要是合并型支链处理得不对。但是在这个过程中坚持了下来,自己不断地发现问题解决问题,直到最后按ad爷说的给自己限定了一个时间,依然没有改过来就去找zzh问了最后一个问题;这样确实能保证效率,而且给了自己一个压力。奥赛课,集中专注、高效紧张是最难的。做了这道题无论是知识上还是心态上都收获很大,时间没有白费。不过剩下的题都没有改,做到一半又舍不得放下,看来像教练说的那样从易到难确实是有必要的(可是我为什么觉得这题除了情况多点其实没有其他题难呢= =)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int nj=,mj=;
int m,n,e,h[nj],fa[nj],c[nj],ans;
bool yh,vi[nj];
int zh,fh,a1,a2,jg,temp;
struct B
{
int v,ne,w;
}b[mj*];
int gcd(int x,int y)
{
if(y==) return x;
return gcd(y,x%y);
}
void add(int x,int y,int z)
{
b[e].v=y;
b[e].ne=h[x];
b[e].w=z;
h[x]=e++;
}
void bj(int &x,int y)
{
x=x>y?x:y;
}
void xbj(int &x,int y)
{
x=x<y?x:y;
}
void dfs(int x,int fx)
{
vi[x]=;
int jk;
for(int i=h[x];i!=-;i=b[i].ne)
{
jk=b[i].v;
if(vi[jk]&&c[x]+b[i].w!=c[jk])
{
if(ans==-) ans=abs(c[x]+b[i].w-c[jk]);
else ans=gcd(ans,abs(c[x]+b[i].w-c[jk]));
yh=;
}
c[jk]=c[x]+b[i].w;
bj(zh,c[jk]);
xbj(fh,c[jk]);
if(!vi[jk])
dfs(jk,b[i].w);
}
}
int find(int x)
{
if(fa[x]==x) return x;
return find(fa[x]);
}
void hb(int x,int y)
{
x=find(x);
y=find(y);
if(x!=y)
fa[x]=y;
}
int main()
{
scanf("%d%d",&n,&m);
memset(h,-,sizeof(h));
ans=-;
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=m;i++)
{
scanf("%d%d",&a1,&a2);
add(a1,a2,);
add(a2,a1,-);
hb(a2,a1);
}
memset(c,,sizeof(c));
for(int i=;i<=n;i++)
if(fa[i]==i)
{
zh=;
fh=0x7fffffff;
temp=fh;
dfs(i,-);
if(zh==&&fh==temp)
jg++;
else
jg+=zh-fh+;
}
if(!yh)
{
if(jg<) printf("-1 -1");
else printf("%d 3",jg);
return ;
}
if(ans<) printf("-1 -1");
else
{
for(int i=;i<=ans;i++)
if((ans%i)==)
{
jg=i;
break;
}
printf("%d %d",ans,jg);
}
return ;
}

假面舞会[NOI2008]的更多相关文章

  1. BZOJ 1064 假面舞会(NOI2008) DFS判环

    此题,回想Sunshinezff学长给我们出的模拟题,原题啊有木有!!此处吐槽Sunshinezff爷出题不人道!! 不过也感谢Sunshinezff学长的帮助,我才能做出来.. 1064: [Noi ...

  2. 图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]

    BZOJ 1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1655  Solved: 798[Submit][S ...

  3. [BZOJ1064][Noi2008]假面舞会

    [BZOJ1064][Noi2008]假面舞会 试题描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢 ...

  4. NOI2008假面舞会

    1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 883  Solved: 462[Submit][Status] ...

  5. 【洛谷】1477:[NOI2008]假面舞会【图论】

    P1477 [NOI2008]假面舞会 题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具 ...

  6. 【BZOJ1064】[Noi2008]假面舞会 DFS树

    [BZOJ1064][Noi2008]假面舞会 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择 ...

  7. 【做题记录】[NOI2008] 假面舞会—有向图上的环与最长链

    luogu 1477 [NOI2008] 假面舞会 容易发现: 如果图中没有环,那么面具种数一定是所有联通块内最长链之和,最少为 \(3\) . 如果有环,则面具种数一定是所有环的大小的最大公约数. ...

  8. 1064: [Noi2008]假面舞会 - BZOJ

    Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办 ...

  9. 【NOI2008】假面舞会(图论,搜索)

    题面 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一个自己喜欢的面 具.每个面具都有一个编号 ...

随机推荐

  1. 自定义分布式RESTful API鉴权机制

    微软利用OAuth2为RESTful API提供了完整的鉴权机制,但是可能微软保姆做的太完整了,在这个机制中指定了数据持久化的方法是用EF,而且对于用户.权限等已经进行了封装,对于系统中已经有了自己的 ...

  2. 如何使用Node.js编写命令工具——以vue-cli为例

    vue-cli全局安装之后,提供了vue命令和vue init.vue list.vue build三个子命令,通过命令可以搭建基于vue.js的脚手架项目.本文简单介绍一下这些命令是如何实现的. v ...

  3. 【LeetCode】94. Binary Tree Inorder Traversal

    题目: Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary ...

  4. Ionic2+ 环境搭建

    ionic2+官方guide 基础环境安装 nodejs安装 ionic,cordova安装 npm install -g ionic cordova 项目创建 ionic start MyIonic ...

  5. Vysor破解助手for Linux/macOS/Windows

    Vysor更新到1.7.8后,之前的破解工具又失效了,但破解的方法依然可用.在更新破解工具的过程中,Vysor又出了1.7.9版本,主要是对Android O做了处理.更新后的破解工具支持1.6.6~ ...

  6. P1280 尼克的任务

    题目描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成. 尼克的一个工作日为N分钟,从第一分钟开始 ...

  7. JavaWeb 后端 <三> 之 Response Request 学习笔记

    一.响应对象 Response(重点:HTTP协议响应部分) 查看

  8. Java基础语法<二> 字符串String

    1. 代码点与代码单元 Java字符串由char序列组成.大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示. length()方法将返回采用UTF-16编码表示 ...

  9. Java 数据类型在实际开发中应用

    在前边的博文中,我已经介绍了Java核心的容器IO等,现在我来说一下java中的数据类型.在java中,一切东西皆为对象(这句话意思是java中绝大数情况都用对象),极少数不是对象的,也存在与之对应的 ...

  10. Android Project和app中两个build.gradle配置的区别

    Android 开发也挺长时间了,从开始就使用的AndroidStudio开发,但是说下来其实自己对AS(AndroidStudio简称)还真的是不了解不深入.好吧,其实我只知道AS是一个相当强大的工 ...