假面舞会[NOI2008]
题目描述
一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会。今年的面具都是主办方特别定制的。每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具。每个面具都有一个编号,主办方会把此编号告诉拿该面具的人。为了使舞会更有神秘感,主办方把面具分为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]的更多相关文章
- BZOJ 1064 假面舞会(NOI2008) DFS判环
此题,回想Sunshinezff学长给我们出的模拟题,原题啊有木有!!此处吐槽Sunshinezff爷出题不人道!! 不过也感谢Sunshinezff学长的帮助,我才能做出来.. 1064: [Noi ...
- 图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]
BZOJ 1064: [Noi2008]假面舞会 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1655 Solved: 798[Submit][S ...
- [BZOJ1064][Noi2008]假面舞会
[BZOJ1064][Noi2008]假面舞会 试题描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢 ...
- NOI2008假面舞会
1064: [Noi2008]假面舞会 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 883 Solved: 462[Submit][Status] ...
- 【洛谷】1477:[NOI2008]假面舞会【图论】
P1477 [NOI2008]假面舞会 题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具 ...
- 【BZOJ1064】[Noi2008]假面舞会 DFS树
[BZOJ1064][Noi2008]假面舞会 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择 ...
- 【做题记录】[NOI2008] 假面舞会—有向图上的环与最长链
luogu 1477 [NOI2008] 假面舞会 容易发现: 如果图中没有环,那么面具种数一定是所有联通块内最长链之和,最少为 \(3\) . 如果有环,则面具种数一定是所有环的大小的最大公约数. ...
- 1064: [Noi2008]假面舞会 - BZOJ
Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办 ...
- 【NOI2008】假面舞会(图论,搜索)
题面 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一个自己喜欢的面 具.每个面具都有一个编号 ...
随机推荐
- c/c++面试准备笔记1
在c++程序中调用被C编译器编译后的函数,为什么要加extern "C"? C++语言支持函数重载,C语言不支持函数重载.函数被C++编译后在库中的名字与C语言的不同.C++提供 ...
- Linux网络编程“惊群”问题总结
1.前言 我从事Linux系统下网络开发将近4年了,经常还是遇到一些问题,只是知其然而不知其所以然,有时候和其他人交流,搞得非常尴尬.如今计算机都是多核了,网络编程框架也逐步丰富多了,我所知道的有多进 ...
- js函数验证方式:验证是否是数字,支持小数,负数
验证 datatype="/^\d+(\.\d+)?$/" validatform验证是否是数字 支持小数点 datatype="d" 貌似支持小数 js函数验 ...
- CentOS yum 安装 PHP 5.6.24
配置yum源 追加CentOS 6.5的epel及remi源. # rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64/epel- ...
- [翻译]成为顶尖程序员应当学什么?Python、C还是Ruby?
原文地址(墙外):https://medium.com/life-tips/should-you-learn-python-c-or-ruby-to-be-a-top-coder-infographi ...
- 【ESP8266】发送HTTP请求
一.ESP8266简介 ESP8266 是深圳安信可科技有限公司开发的基于乐鑫ESP8266的超低功耗的UART-WIFI模块的模组,可以方便进行二次元开发,接入云端服务,实现手机3/4G全球随时随地 ...
- 同网段电脑互ping
两台同网段的主机(host)之间的网络通信是不经过网关的. 今天试了一下,用一根网线连接两台电脑,然后 在一台电脑上设置: ip地址:192.168.0.1 子网掩码:255.255.255.0 在另 ...
- 读书共享 Primer Plus C-part 8
第十三章 文件输入/输出 fopen--fclose fopen 是文件的操作的开始 fclose是文件操作的结束 getc--putc getchar--putchar getc对应文件的获取单个字 ...
- 基于Bootstrap+angular的一个豆瓣电影app
1.搭建项目框架 npm初始化项目 npm init -y //按默认配置初始化项目 安装需要的第三方库 npm install bootstrap angular angular-route --s ...
- Angular表单控件需要类型和实际值类型不一致时实现双向绑定
适用Angular版本为:>=2.本文同样适用于Ionic这类的基于Angular实现的框架. 本文的思路也适用于控件显示的值和实际的值不一样时实现双向绑定. 1. 问题描述 在使用md2的da ...