题目描述

一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会。

今年的面具都是主办方特别定制的。每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具。每个面具都有一个编号,主办方会把此编号告诉拿该面具的人。

为了使舞会更有神秘感,主办方把面具分为\(k (k \ge 3)\)类,并使用特殊的技术将每个面具的编号标在了面具上,只有戴第$i \(类面具的人才能看到戴第\)i+1$ 类面具的人的编号,戴第$k $类面具的人能看到戴第\(1\) 类面具的人的编号。

参加舞会的人并不知道有多少类面具,但是栋栋对此却特别好奇,他想自己算出有多少类面具,于是他开始在人群中收集信息。

栋栋收集的信息都是戴第几号面具的人看到了第几号面具的编号。如戴第2号面具的人看到了第5 号面具的编号。栋栋自己也会看到一些编号,他也会根据自己的面具编号把信息补充进去。

由于并不是每个人都能记住自己所看到的全部编号,因此,栋栋收集的信 息不能保证其完整性。现在请你计算,按照栋栋目前得到的信息,至多和至少有多少类面具。由于主办方已经声明了\(k \ge 3\),所以你必须将这条信息也考虑进去。

输入输出格式

输入格式

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

输出格式

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

题解

很明显我们需要考虑环和链:对于链来说无论这条链有多长,所允许的面具的个数都是任意的(注意:最小要为3);对于一个环来说最多的面具数一定是这个环的大小,而且,当面具的个数为该环长的约数时也是符合要求的。

根据以上两点,我们就能够很轻松地想出我们的答案可以分为两类:一类是只有链的,就是最长链的长度和3了;另一类就是要考虑有环的情况,就是所有环的环长的最大公约数和大于3的最小公约数。而当最大答案都小于3的时候就是无解了。

建图技巧

我们需要Get到每个环的环长和链的链长,有下述的建图技巧:

我们可以把每条有向边\((u, v)\)分成两条,一条是\((u,v)\)权值为\(1\), 一条是\((v, u)\)权值为\(-1\), 而这样的两条边有什么好处呢?这样我们就可以方便求出无环图的链长和环长了。

比如说下图:



按照上面说的建图方式,我们可以得到这样的图(黑边权值为1,蓝边为-1):



然后我们按照 \(2 \Rightarrow 1 \Rightarrow 6 \Rightarrow 3 \Rightarrow 4 \Rightarrow 5\) 的顺序遍历然后把每个点的点权记作\(p_i\), 令\(p_2 = 0\) 于是,我们可以得到如图所示的点权(红色数字),这样,当我们遍历到\(5\)时我们发现了一条边\((5, 6)\) 可以到结点 \(6\) ,而 \(6\) 我们已经遍历过了,证明有环,而环长就应该为 $abs(p_5 - p_6 + len(5, 6)) =abs(3 - 0 + 1) = 4 $

求链长也同理的,对于一个无环图,最长链即为\(p_{max} - p_{min} + 1\)

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100005, MAXM = 1000005; inline int gcd(int a, int b)
{
return !b ? a : gcd(b, a % b);
} int Head[MAXN], Next[MAXM << 1], To[MAXM << 1], w[MAXM << 1], edgenum;
inline void Add_edge(int from, int to, int cost)
{
Next[++ edgenum] = Head[from], Head[from] = edgenum, To[edgenum] = to, w[edgenum] = cost;
} int minn[MAXN], maxn[MAXN], p[MAXN], vis[MAXN], root;
int ans = 0;
inline void dfs(int u)
{
minn[root] = min(minn[root], p[u]), maxn[root] = max(maxn[root], p[u]), vis[u] = 1;
for(int i = Head[u]; i != -1; i = Next[i])
{
int v = To[i];
if(vis[v]) ans = gcd(ans, abs(p[u] - p[v] + w[i]));
else{
p[v] = p[u] + w[i];
dfs(v);
}
}
} int fa[MAXN];
inline int find(int x)
{
return x == fa[x] ? x : fa[x] = find(fa[x]);
} int main()
{
int n, m, ans1 = 0, ans2 = 0;
memset(Head, -1, sizeof(Head));
memset(minn, 0x3f, sizeof(minn)); scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i) fa[i] = i;
int x, y;
for(int i = 1; i <= m; ++ i)
{
scanf("%d%d", &x, &y);
Add_edge(x, y, 1), Add_edge(y, x, -1);
x = find(x), y = find(y);
if(x != y) fa[x] = y;
}
for(int i = 1; i <= n; ++ i)
if(!vis[i])
{
root = find(i);
dfs(root);
}
ans1 = ans;
for(int i = 3; i <= ans1; ++ i)
if(! (ans1 % i))
{
ans2 = i; break;
}
if(ans2 < 3) ans2 = 3;
root = 0;
if(ans1 == 0)
for(int i = 1; i <= n; ++ i)
if(fa[i] == i)
root += maxn[i] - minn[i] + 1;
if(ans1 == 0) ans1 = root;
if(ans1 < 3) ans1 = ans2 = -1;
printf("%d %d\n", ans1, ans2);
return 0;
}

【NOI2008】假面舞会的更多相关文章

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

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

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

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

  3. NOI2008假面舞会

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

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

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

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

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

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

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

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

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

  8. 【BZOJ】1064: [Noi2008]假面舞会(判环+gcd+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1064 表示想到某一种情况就不敢写下去了.... 就是找环的gcd...好可怕.. 于是膜拜了题解.. ...

  9. 洛谷 P1477 [NOI2008]假面舞会

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

  10. BZOJ1064 [Noi2008]假面舞会 【dfs】

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

随机推荐

  1. table中td 内容超长 自动折行 (含字母数字文字)

    <table style="width:100%;table-layout:fixed;"> //列宽由表格宽度和列宽度设定 <thead> <th& ...

  2. 激活 IntelliJ IDEA

    1.点击下面的链接下载 JetbrainsIdesCrack-4.2-release.jar 链接:https://pan.baidu.com/s/1eNY_bwxF7Efl4QG0yh6l1A  提 ...

  3. C#PrintDocument打印尺寸调整

    /// <summary> /// 打印的按钮 /// </summary> /// <param name="sender"></par ...

  4. 撩课-Python-每天5道面试题-第9天

    一. Python程序中, 文件的处理步骤是什么? 打开 open("文件","模式") 读写 2.1 读 f.read(字节数) 字节数默认是文件内容长度 下 ...

  5. jvm 类文件结构学习

    本文以代码示例来学习 java 类文件的结构,其中对类文件结构的学习均来自周志明先生所著的 <深入理解 Java 虚拟机>一书,在此表示诚挚的感谢. 代码如下: package com.r ...

  6. python中字符串格式化%与.format

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  7. 关于echarts绘制树图形的注意事项(文字倾斜、数据更新、缓存重绘问题等)

    最近项目中使用到echarts的树操作,对其中几点注意事项进行下总结. 效果图: 1.基础配置 options的配置如下: { tooltip: { trigger: 'item', triggerO ...

  8. js 判断 复选框全选、全不选、反选、必选一个

    一个挺 使用的 js 代码片段,  判断  复选框全选.全不选.反选.必选一个 记录下, 搬来的 思路: 修改数据的 选中与否状态, 拿到所有的输入框,看是否有选中的状态 <html> & ...

  9. python学习笔记之——正则表达式

    1.re模块 Python通过re模块提供对正则表达式的支持,re 模块使 Python 语言拥有全部的正则表达式功能.使用re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用 ...

  10. sudo的安装

    关于mini版的centos7的是不能直接sudo命令的 下面我来说一下怎么让sudo命令生效 第一步 先切换到root用户: su -    第二步 visudo 给相应用户分配sudo的权限 第三 ...