题目

一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会。今年的面具都是主办方特别定制的。每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具。每个面具都有一个编号,主办方会把此编号告诉拿该面具的人。为了使舞会更有神秘感,主办方把面具分为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

输出样例

4 4

提示

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

题解

根据题目的描述,所有人的关系形成一种环状关系

假若给出的关系中存在环,那么环长一定是k的倍数

设所有环长的gcd为x,此时答案为[x大于3的因子,x]

假若没有环,结果就是所有最长链之和

现在问题是如何求环以及最长链

有一种dfs的方法很厉害

我们将原边赋值为1,建一个反边赋值为-1,这样就构造出了一个类似无向图的东西,我们就可以从一个点出发访问整个联通块

由于-1的存在,走反边会导致负值,走正边会形成正值,这样两点间长度就可以用差来求出

跑dfs时,遇到了返祖边,则形成环,统计答案,同时统计这个联通块的最小权值和最大权值,只差 + 1即为最长链长度

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 100005,maxm = 2000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
int h[maxn],ne = 2;
struct EDGE{int to,nxt,w;}ed[maxm];
void build(int u,int v){
ed[ne] = (EDGE){v,h[u],1}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v],-1}; h[v] = ne++;
}
int n,m,f[maxn],vis[maxn],pre[maxn],gmax[maxn],gmin[maxn],now;
int ansl,ansr;
int gcd(int a,int b){return b ? gcd(b,a % b) : a;}
int find(int u){return u == pre[u] ? u : pre[u] = find(pre[u]);}
void dfs(int u,int last){
gmax[now] = max(gmax[now],f[u]);
gmin[now] = min(gmin[now],f[u]);
vis[u] = true;
Redge(u) if ((k ^ 1) != last){
if (!vis[to = ed[k].to]) f[to] = f[u] + ed[k].w,dfs(to,k);
else {
ansr = gcd(abs(f[u] + ed[k].w - f[to]),ansr);
//printf("%d to %d\n",u,to);
}
}
}
int main(){
n = read(); m = read();
int a,b,fa,fb;
for (int i = 1; i <= n; i++) pre[i] = i;
while (m--){
a = read(); b = read();
build(a,b);
fa = find(a); fb = find(b);
if (fa != fb) pre[fb] = fa;
}
for (int i = 1; i <= n; i++) if (!vis[i]) now = find(i),dfs(i,0);
if (ansr){
for (int i = 3; i <= ansr; i++) if (ansr % i == 0){ansl = i; break;}
if (ansl < 3) puts("-1 -1");
else printf("%d %d\n",ansr,ansl);
}else {
for (int i = 1; i <= n; i++) if (find(i) == i) ansr += (gmax[i] - gmin[i] + 1);
if (ansr < 3) puts("-1 -1");
else printf("%d 3\n",ansr);
}
return 0;
}

BZOJ1064 [Noi2008]假面舞会 【dfs】的更多相关文章

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

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

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

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

  3. 【图论 搜索】bzoj1064: [Noi2008]假面舞会

    做到最后发现还是读题比赛:不过还是很好的图论题的 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选 ...

  4. BZOJ1064 NOI2008假面舞会(dfs树)

    将图中的环的长度定义为正向边数量-反向边数量,那么答案一定是所有环的环长的共同因子.dfs一下就能找到图中的一些环,并且图中的所有环的环长都可以由这些环长加加减减得到(好像不太会证).如果有环长为1或 ...

  5. [bzoj 1064][NOI2008]假面舞会(dfs判断环)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1064 分析: 如果a看到b,则a->b 那么: 1.如果图中有环,则说明这个环的 ...

  6. BZOJ1064 NOI2008 假面舞会 图论

    传送门 将一组关系\((A,B)\)之间连一条边,那么显然如果图中存在环长为\(len\)的环,那么面具的种数一定是\(len\)的因数. 值得注意的是这里环的关系除了\(A \rightarrow ...

  7. BZOJ1064 NOI2008假面舞会

    挺神的这题,发现只有环和链两种情况 搜索时我们只考虑环的,因为链可以看成找不到分类的环. 当成链时大小是的最大值是各链长的和,最小值是3 当成环时最大值是各环长的gcd,最小值是大于3的最小的ans的 ...

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

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

  9. NOI2008假面舞会

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

随机推荐

  1. 贪心水题。UVA 11636 Hello World,LA 3602 DNA Consensus String,UVA 10970 Big Chocolate,UVA 10340 All in All,UVA 11039 Building Designing

    UVA 11636 Hello World 二的幂答案就是二进制长度减1,不是二的幂答案就是是二进制长度. #include<cstdio> int main() { ; ){ ; ) r ...

  2. 读书笔记-《深入理解Java虚拟机:JVM高级特性与最佳实践》

    目录 概述 第一章: 走进Java 第二章: Java内存区域与内存溢出异常 第三章: 垃圾收集器与内存分配策略 第四章: 虚拟机性能监控与故障处理 第五章: 调优案例分析与实战 第六章: 类文件结构 ...

  3. java基础—线程(二)

    一.线程的优先级别

  4. 66. Plus One@python

    Given a non-empty array of digits representing a non-negative integer, plus one to the integer. The ...

  5. 【Machine Learning is Fun!】1.The world’s easiest introduction to Machine Learning

    Bigger update: The content of this article is now available as a full-length video course that walks ...

  6. MySQL多源复制

    MySQL多源复制 1. 配置多源复制 1.1 配置环境如下 1.2 从库的重要参数配置 1.3 在Master上导出需要同步的数据库 1.4 在master上创建复制账号 1.5 备份数据导入 1. ...

  7. day3-python 登录

    import datetime # 1. f = open('users') result = f.read() f.close() user_list = result.split() # user ...

  8. Linux系统入门-Bash初识

    目录 Linux系统入门-Bash初识 Bash Shell介绍 Bash Shell的作用 Bash的两种使用方式 命令提示符 shell的基础语法 shell的基本特性 命令补全 linux快捷键 ...

  9. Django ORM (三) 查询,删除,更新操作

    ORM 查询操作 修改 views.py 文件 from django.shortcuts import render, HttpResponse from app01 import models f ...

  10. python基本操作(四)

    与用户交互 为什么交互? 计算机取代人类,解放劳动力 如何交互 print('-'*100) input('请输入你的姓名:') print(""100) Python2和Pyth ...