BZOJ1064 NOI2008 假面舞会 图论
将一组关系\((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 假面舞会 图论的更多相关文章
- [BZOJ1064][Noi2008]假面舞会
[BZOJ1064][Noi2008]假面舞会 试题描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢 ...
- 【图论 搜索】bzoj1064: [Noi2008]假面舞会
做到最后发现还是读题比赛:不过还是很好的图论题的 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选 ...
- BZOJ1064 [Noi2008]假面舞会 【dfs】
题目 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿 ...
- BZOJ1064 NOI2008假面舞会(dfs树)
将图中的环的长度定义为正向边数量-反向边数量,那么答案一定是所有环的环长的共同因子.dfs一下就能找到图中的一些环,并且图中的所有环的环长都可以由这些环长加加减减得到(好像不太会证).如果有环长为1或 ...
- 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 ...
- 【洛谷】1477:[NOI2008]假面舞会【图论】
P1477 [NOI2008]假面舞会 题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具 ...
- NOI2008假面舞会
1064: [Noi2008]假面舞会 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 883 Solved: 462[Submit][Status] ...
随机推荐
- odoo:开源 ERP/CRM 入门与实践
看了这张图,或许你对odoo有了一些兴趣. 这次就是和大家一起交流开源ERP/CRM系统:odoo 对以下读者有帮助:研发.产品.项目.市场.服务.运营.管理等. 一.背景趋势 社交网络.电商O2O: ...
- MySQL 横向表分区之RANGE分区小结
MySQL 横向表分区之RANGE分区小结 by:授客 QQ:1033553122 目录 简介 1 RANGE分区 1 创建分区表 1 查看表分区 2 新增表分区 2 新增数据 3 分区表查询 3 删 ...
- PyCharm 专业版激活方法
郑重声明: JetBrains公司的PyCharm专业版是收费的,本文所述激活方法仅限于短时内体验和试用PyCharm专业版,使用后请当天立即删除.若需要继续使用PyCharm专业版,请在官网购买.当 ...
- python使用sax实现xml解析
之前在使用xml解析的时候,在网上搜了很多教程,最终没有能按照网上的教程实现需求. 所以呢,只好自己去看源码,在sax的__init__.py下看到这么一段代码: 1 def parse(source ...
- 口碑点餐相关问题FAQ
1.菜品上传中:出现重复错误或者违禁词 检查并修改商家中心本次上传中的重复菜品,或者删除口碑掌柜以及第三方平台已添加的重复菜品(重复菜品临时快捷办法:修改菜品名称) 2.手持pos 打开自动接单,无响 ...
- coTurn 运行在Windows平台的方法及服务与客户端运行交互流程和原理
coTurn是一个开源的STUN和TURN及ICE服务项目,只是不支持Windows.为了在window平台上使用coTurn源码,需要在windows平台下安装Cygwin环境,并编译coTurn源 ...
- C#-类(九)
类的定义 类是描述具有相同特征与行为的事物的抽象,类内部包含类的特征和类的行为 类支持继承 类的定义是关键字class为标志 类的格式 访问标识符 class 类名 { 类主体 } 访问标识符:指定了 ...
- Pythonic是什么?
Python 之禅之中有这样几句话: 优美胜于丑陋(Python 以编写优美的代码为目标) 明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似) 简洁胜于复杂(优美的代码应当是简洁的,不要有复杂 ...
- Cesium实现键盘控制镜头效果
w-前进 a-左转 d-右转 s-后退 q-上仰 鼠标左键按住左右移动更换角度 html代码如下: <div id="cesiumContainer" style= ...
- 如何使用JVisualVM进行性能分析
地址:https://visualvm.dev.java.net/ 连接 1.本地机器的程序直接可以监听到 2.远程机器的程序需要加上JVM参数 -Dcom.sun.management.jmxrem ...