[BZOJ1064][Noi2008]假面舞会
[BZOJ1064][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。
输入示例1
输出示例1
输入示例2
输出示例2
- -
数据规模及约定
100%的数据,满足n ≤ 100000, m ≤ 1000000。
题解
先看看我们知道什么。假设一个合法的答案是 k,则给了一条有向边(a, b)后,就说明 a 在第 i 组且 b 在第 i + 1 组,或者是 a 在第 k 组且 b 在第 1 组。
不难想到当给定的有向边形成一个环之后,k 一定是这个环长度的约数(因为它可以从第 1 组某个节点连到第 2 组某个节点,一直连到第 k 组某个节点,再从第 k 组的那个节点直接连一条边到第 1 组的某个节点,如此往复最终首尾相接,则这个环绕了若干圈这 k 个组)。
还有一种情况:a -> b -> c -> d -> e 且 a -> e,我们可以尝试给它分组,先考虑前面那条链,可以暂时将它们分成这个样子:a∈1,b∈2,c∈3,d∈4,e∈5,那么再加上 a -> e 这条边后发现 e 的编号应该等于 a 的编号加 1,所以将其与 b 分到第 2 组,同理 a 的编号应该等于原来 e 的编号减 1,所以将其与 d 分到第 4 组,最终结果是:b, e∈2,c∈3,a, d∈4,最终组数为 3。
综上两点可以得出一种做法:从每个连通分量的一个节点开始标号,顺着有向边走时标号加 1,逆着走时减 1,发现当前结点有标号时,则最大答案就是所有这种情况中的“原标号与新标号之差的绝对值”取最大公约数,最小答案就是所有所有这样的值取大于等于 3 的最小公约数。
注意一个特判,当给的图在以上两种情况之外,即将有向边变成无向边后没有圈的图(成为一个森林)时,每个连通分量的最大标号 - 最小标号 + 1,求和就是最大答案,最小答案是 3(若合法).
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 100010
#define maxm 2000010
#define oo 2147483647
int n, m, head[maxn], next[maxm], to[maxm], dist[maxm], ans; void AddEdge(int a, int b) {
to[++m] = b; dist[m] = 1; next[m] = head[a]; head[a] = m;
swap(a, b);
to[++m] = b; dist[m] = -1; next[m] = head[a]; head[a] = m;
return ;
} int gcd(int a, int b) { return !b ? a : gcd(b, a % b); } int mark[maxn], mx, mn;
bool vis[maxn];
void dfs(int u, int x) {
if(vis[u]){ ans = gcd(ans, abs(mark[u] - x)); return ; }
vis[u] = 1; mark[u] = x; mx = max(mx, x); mn = min(mn, x);
for(int e = head[u]; e; e = next[e]) dfs(to[e], x + dist[e]);
return ;
} int main() {
n = read(); int m = read();
for(int i = 1; i <= m; i++) {
int a = read(), b = read();
AddEdge(a, b);
} int tmp = 0;
for(int i = 1; i <= n; i++) if(!vis[i]) {
mx = -oo; mn = oo;
dfs(i, 1);
tmp += mx - mn + 1;
}
int a2;
if(!ans) ans = tmp, a2 = 3;
else for(a2 = 3; a2 <= ans && ans % a2; a2++) ;
if(ans < 3) puts("-1 -1");
else printf("%d %d\n", ans, a2); return 0;
}
[BZOJ1064][Noi2008]假面舞会的更多相关文章
- BZOJ1064 [Noi2008]假面舞会 【dfs】
题目 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿 ...
- 【图论 搜索】bzoj1064: [Noi2008]假面舞会
做到最后发现还是读题比赛:不过还是很好的图论题的 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选 ...
- BZOJ1064 NOI2008假面舞会(dfs树)
将图中的环的长度定义为正向边数量-反向边数量,那么答案一定是所有环的环长的共同因子.dfs一下就能找到图中的一些环,并且图中的所有环的环长都可以由这些环长加加减减得到(好像不太会证).如果有环长为1或 ...
- BZOJ1064 NOI2008 假面舞会 图论
传送门 将一组关系\((A,B)\)之间连一条边,那么显然如果图中存在环长为\(len\)的环,那么面具的种数一定是\(len\)的因数. 值得注意的是这里环的关系除了\(A \rightarrow ...
- BZOJ1064 NOI2008假面舞会
挺神的这题,发现只有环和链两种情况 搜索时我们只考虑环的,因为链可以看成找不到分类的环. 当成链时大小是的最大值是各链长的和,最小值是3 当成环时最大值是各环长的gcd,最小值是大于3的最小的ans的 ...
- 【BZOJ1064】[Noi2008]假面舞会 DFS树
[BZOJ1064][Noi2008]假面舞会 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择 ...
- 图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]
BZOJ 1064: [Noi2008]假面舞会 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1655 Solved: 798[Submit][S ...
- NOI2008假面舞会
1064: [Noi2008]假面舞会 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 883 Solved: 462[Submit][Status] ...
- 【洛谷】1477:[NOI2008]假面舞会【图论】
P1477 [NOI2008]假面舞会 题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具 ...
随机推荐
- Spring学习(三)——Spring中的依赖注入的方式
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...
- 《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(1)-读书笔记
章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...
- NoSQL数据库之国产开源产品:SequoiaDB 分析前言
随着互联网技术的发展,面对海量数据的存储和分析,传统关系型数据库已经无法满足,由此衍生出一种与关系型数据库区别开的数据库NoSQL(Not Only SQL). 国外做的比较成熟的NoSQL有Mong ...
- java web中jsp,action,service,dao,po分别是什么意思和什么作用
JSP:全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它[1] 是由Sun Microsystems公司倡导.许多公司参与一起建立的一种动 ...
- OC基础--block
block与函数类似:1.可以保存代码 2.又返回值 3.有形参 4.调用方式一样 block的标志:^ 一.定义一个无参无返回值的block void (^myBlock)();--1.void 代 ...
- js库中$冲突的解决方法
http://www.w3school.com.cn/jquery/core_noconflict.asp
- Java-Stack
package 集合类.list类; import java.util.Date; import java.util.Stack; /** * stack类继承与vector类 * @author j ...
- 【UVALive 3905】BUPT 2015 newbie practice #2 div2-D-3905 - Meteor
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=102419#problem/D The famous Korean internet co ...
- JAVA的整型与字符串相互转换
1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([S ...
- Erlang练习题----shopping
直接就上代码了: -module(shop). -export([cost/1,total/1]). cost(orange) -> 5; cost(newspaper) -> 8; co ...