传送门


将一组关系\((A,B)\)之间连一条边,那么显然如果图中存在环长为\(len\)的环,那么面具的种数一定是\(len\)的因数。

值得注意的是这里环的关系除了\(A \rightarrow B \rightarrow C \rightarrow D \rightarrow A\)类型以外,\(A \rightarrow B \rightarrow C \rightarrow D + A \rightarrow D\)也是一种环,而后者的环长为\(3 - 1 = 2\),是两条路的路径之差。为了方便计算后面这种环,改变一下加边方式,对于一组关系\((A,B)\)从\(A\)向\(B\)连一条权值为\(1\)的边,从\(B\)往\(A\)连一条权值为\(-1\)的边,这样两种环都可以在图上表示出来。

找环的方法就是先抽出一棵DFS树,对于每一条非树边加进去出现的环计算贡献。

注意如果某一个环中存在\(\geq 2\)条非树边,可以不统计入答案:不妨证明有\(2\)条非树边的情况。设两条边是\(A \rightarrow B\)和\(C \rightarrow D\),DFS树根为\(E\),那么存在有两条非树边的环\(E \rightarrow D \rightarrow C \rightarrow B \rightarrow A \rightarrow E\),且同时存在\(E \rightarrow D \rightarrow C \rightarrow E\)和\(E \rightarrow B \rightarrow A \rightarrow E\)。经过\(2\)条非树边的环的权值正是后两条经过一条非树边的环的权值和,而\(gcd(a,b) = gcd(a , a+b) = gcd(b , a + b)\),所以在后两个环加入答案的情况下,\(E \rightarrow D \rightarrow C \rightarrow B \rightarrow A \rightarrow E\)在答案中没有意义的。

如果图中有环,那么最后的最大答案就是所有环长的\(gcd\),最小答案就是\(gcd\)因子中\(\geq 3\)的最小的那个。

如果图中没有环,因为可以连边把所有连通块连起来,那么最大答案就是所有连通块中的最长链的权值之和,最小答案就是\(3\)。

注意如果图中没有环而最长链权值之和\(\leq 3\)是要输出\(-1\ -1\)而不是\(3\ 3\)的

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<queue>
#define INF 0x3f3f3f3f
//This code is written by Itst
using namespace std; inline int read(){
int a = 0;
char c = getchar();
while(!isdigit(c) && c != EOF)
c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
} const int MAXN = 100007;
struct Edge{
int end , upEd , w;
}Ed[MAXN * 20];
int head[MAXN] , dis[MAXN] , N , M , cntEd , ans , minN , maxN , sum;
bool vis[MAXN]; inline int gcd(int a , int b){
if(!a || !b) return a + b;
a = a < 0 ? -a : a; b = b < 0 ? -b : b;
int r = a % b;
while(r){a = b; b = r; r = a % b;}
return b;
} inline void addEd(int a , int b , int c){
Ed[++cntEd] = (Edge){b , head[a] , c};
head[a] = cntEd;
} void dfs(int x){
minN = min(minN , dis[x]); maxN = max(maxN , dis[x]);
vis[x] = 1;
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(!vis[Ed[i].end]){
dis[Ed[i].end] = dis[x] + Ed[i].w;
dfs(Ed[i].end);
}
else
ans = gcd(ans , dis[x] - dis[Ed[i].end] + Ed[i].w);
} int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
N = read(); M = read();
for(int i = 1 ; i <= M ; ++i){
int a = read() , b = read();
addEd(a , b , 1); addEd(b , a , -1);
}
for(int i = 1 ; i <= N ; ++i)
if(!vis[i]){
minN = maxN = 0;
dfs(i);
sum += maxN - minN + 1;
}
if(!ans)
if(sum >= 3) cout << sum << " 3";
else cout << "-1 -1";
else if(ans <= 2) cout << "-1 -1";
else
for(int j = 3 ; j <= ans ; ++j)
if(ans % j == 0){
cout << ans << ' ' << j;
break;
}
return 0;
}

BZOJ1064 NOI2008 假面舞会 图论的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ1064 NOI2008假面舞会

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

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

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

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

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

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

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

  9. NOI2008假面舞会

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

随机推荐

  1. Deep Learning - 2 反向传播

    深度神经网络的学习基于两个关键技术: Stochastic Gradient Descent Backpropagation 利用 SGD 算法学习 Weights 和 Biases,利用 Backp ...

  2. python+selenium+PhantomJS爬取网页动态加载内容

    一般我们使用python的第三方库requests及框架scrapy来爬取网上的资源,但是设计javascript渲染的页面却不能抓取,此时,我们使用web自动化测试化工具Selenium+无界面浏览 ...

  3. Web前端:博客美化:二、鼠标特效

    1.获取JS权限 因为是js代码所以需要放在 侧边栏公告 里 没开通之前,有一个申请的链接,点击即可,我是第二天才看到过审的 ^-^ 2.Ctrl+C.Ctrl+V 数组里的文字随自己心情啦 另:30 ...

  4. Docker Data Center系列(四)- 离线安装UCP和DTR

    本系列文章演示如何搭建一个mini的云平台和DevOps实践环境. 基于这套实践环境,可以部署微服务架构的应用栈,演练提升DevOps实践能力. 1 离线安装UCP 1.1 可用版本 Version ...

  5. CSS杂谈(2)

    opacity 属性设置元素的不透明级别.   语法 opacity: value|inherit; 值 描述   value 规定不透明度.从 0.0 (完全透明)到 1.0(完全不透明).   i ...

  6. c#核心基础--类的构造方法

    一.构造方法 类的构造方法是类的成员方法的一种,它的作用是对类中的成员进行初始化操作.类的构造方法分为: 1.静态构造方法 2.实例构造方法 3.私有构造方法 1.静态构造方法 类的静态构造方法是类的 ...

  7. onclick="return function()"的使用情况

    根据function的返回值,进行下一步操作,当返回值为true时,进行下一步操作,当返回值为false时,不进行操作. 例如:当在 <a href="url" onclic ...

  8. 关于getdate()的不同的日期格式

    在使用Sql Server查询数据库时,我们经常会需要查询日期格式的数据,对于日期在sql语言中的格式有一定的要求,通过修改convert中的最后一位参数,可以返回不通格式的时间,具体实现如下: Se ...

  9. SQL SERVER查询字段在哪个表里

    ); SET @ColumnName='字段名的模糊匹配'; SELECT 表名=D.NAME, 表说明 THEN ISNULL(F.VALUE, ' ') ELSE ' ' END, 字段序号 = ...

  10. IPerf——网络测试工具介绍与源码解析(4)

    上篇随笔讲到了TCP模式下的客户端,接下来会讲一下TCP模式普通场景下的服务端,说普通场景则是暂时不考虑双向测试的可能,毕竟了解一项东西还是先从简单的情况下入手会快些. 对于服务端,并不是我们认为的直 ...