Luogu P1477 [NOI2008]假面舞会
一道非常神奇的图论题解法无比新奇清新
我们首先把图分成三种情况:
- 有环的,此时答案一定是环长的因数(否则不能满足题意)
- 存在入度大于1的DAG图的
- 一棵树/一条链
很容易发现,最后一种情况想怎么取就怎么取,那么我们只需要考虑1,2的影响即可
但是如果我们傻乎乎地直接跑好像也是可以的那就太烦了。
我们考虑这样的一个图:

我们把原图中的边分成两类:红色(顺时针)和绿色(逆时针)。然后我们发现这种图对应上面讲的情况2。然后手推颜色发现要两种。
而这个2是怎么来的,很简单,\(color=| total_{red}-total_{green} |\)。为什么,我们仔细观察一下对于每一个被一条顺时针边和一条逆时针边连接的点,与它相连的点颜色一定相同
然后我们就可以把问题转化成无向边并找环了。但是图中的边并没有顺时针/逆时针,于是我们分成正向边/反向边考虑即可。
可以设为相反的边权(如\(1 \&\& -1\)等)。然后取绝对值即可。
然后对于有环的情况(无论时1还是2),我们都可以得出\(ans=gcd(|len|)\),其中\(len\)表示环长,那么最小值就是\(min(ans|u)\)
值得注意的还有森林的情况,稍加推到此时的\(ans=\sum maxdis-mindis+1 \ (for\ each\ Unicom\ blocks\ of \ the\ gragh)\)
最后当得到的\(ans<3\)时无解。找环当然是BFS/DFS了(注意不要把环和SCC搞混了)
BFS版CODE
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
const int N=100005,M=1000005;
struct edge
{
int to,next,v;
}e[M<<1];
int head[N],dis[N],q[N],n,m,x,y,ans,lans,sum,cnt,MIN,MAX;
bool vis[N];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void double_add(int x,int y)
{
e[++cnt].to=y; e[cnt].v=1; e[cnt].next=head[x]; head[x]=cnt;
e[++cnt].to=x; e[cnt].v=-1; e[cnt].next=head[y]; head[y]=cnt;
}
inline int gcd(int n,int m)
{
return m?gcd(m,n%m):n;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline int max(int a,int b)
{
return a>b?a:b;
}
inline void BFS(int s)
{
register int i,H=0,T=1; vis[s]=1; q[1]=s;
while (H<T)
{
int now=q[++H];
for (i=head[now];~i;i=e[i].next)
if (vis[e[i].to]) ans=gcd(ans,dis[now]-dis[e[i].to]+e[i].v); else
{
dis[e[i].to]=dis[now]+e[i].v; vis[e[i].to]=1; q[++T]=e[i].to;
MIN=min(MIN,dis[e[i].to]); MAX=max(MAX,dis[e[i].to]);
}
}
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i; read(n); read(m);
memset(head,-1,sizeof(head)); memset(e,-1,sizeof(e));
for (i=1;i<=m;++i)
read(x),read(y),double_add(x,y);
for (i=1;i<=n;++i)
if (!vis[i])
{
MAX=MIN=0; BFS(i);
sum+=MAX-MIN+1;
}
if (ans<0) ans=-ans;
if (ans)
{
if (ans<3) return puts("-1 -1"),0;
for (lans=3;lans<ans&&ans%lans;++lans);
return printf("%d %d",ans,lans),0;
}
if (sum<3) return puts("-1 -1"),0;
return printf("%d 3",sum),0;
}
DFS版CODE
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
const int N=100005,M=1000005;
struct edge
{
int to,next,v;
}e[M<<1];
int head[N],dis[N],n,m,x,y,ans,lans,sum,cnt,MIN,MAX;
bool vis[N];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void double_add(int x,int y)
{
e[++cnt].to=y; e[cnt].v=1; e[cnt].next=head[x]; head[x]=cnt;
e[++cnt].to=x; e[cnt].v=-1; e[cnt].next=head[y]; head[y]=cnt;
}
inline int gcd(int n,int m)
{
return m?gcd(m,n%m):n;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline int max(int a,int b)
{
return a>b?a:b;
}
inline void DFS(int now)
{
register int i; vis[now]=1;
for (i=head[now];~i;i=e[i].next)
if (vis[e[i].to]) ans=gcd(ans,dis[now]-dis[e[i].to]+e[i].v);
else MIN=min(MIN,dis[e[i].to]=(dis[now]+e[i].v)),MAX=max(MAX,dis[e[i].to]),DFS(e[i].to);
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i; read(n); read(m);
memset(head,-1,sizeof(head)); memset(e,-1,sizeof(e));
for (i=1;i<=m;++i)
read(x),read(y),double_add(x,y);
for (i=1;i<=n;++i)
if (!vis[i])
{
MAX=MIN=0; DFS(i);
sum+=MAX-MIN+1;
}
if (ans<0) ans=-ans;
if (ans)
{
if (ans<3) return puts("-1 -1"),0;
for (lans=3;lans<ans&&ans%lans;++lans);
return printf("%d %d",ans,lans),0;
}
if (sum<3) return puts("-1 -1"),0;
return printf("%d 3",sum),0;
}
Luogu P1477 [NOI2008]假面舞会的更多相关文章
- 洛谷 P1477 [NOI2008]假面舞会
题目链接 题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方 ...
- 【洛谷】1477:[NOI2008]假面舞会【图论】
P1477 [NOI2008]假面舞会 题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具 ...
- 【做题记录】[NOI2008] 假面舞会—有向图上的环与最长链
luogu 1477 [NOI2008] 假面舞会 容易发现: 如果图中没有环,那么面具种数一定是所有联通块内最长链之和,最少为 \(3\) . 如果有环,则面具种数一定是所有环的大小的最大公约数. ...
- 图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]
BZOJ 1064: [Noi2008]假面舞会 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1655 Solved: 798[Submit][S ...
- [BZOJ1064][Noi2008]假面舞会
[BZOJ1064][Noi2008]假面舞会 试题描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢 ...
- NOI2008假面舞会
1064: [Noi2008]假面舞会 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 883 Solved: 462[Submit][Status] ...
- 【BZOJ1064】[Noi2008]假面舞会 DFS树
[BZOJ1064][Noi2008]假面舞会 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择 ...
- 1064: [Noi2008]假面舞会 - BZOJ
Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办 ...
- 【BZOJ】1064: [Noi2008]假面舞会(判环+gcd+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1064 表示想到某一种情况就不敢写下去了.... 就是找环的gcd...好可怕.. 于是膜拜了题解.. ...
随机推荐
- Linux 改动inittab文件及忘记密码等导致无法进入系统的解决办法
改动inittab文件及忘记密码等导致无法进入系统的解决办法[摘] by:授客 QQ:1033553122 inittab是linux的系统启动模式配置文件,在”/etc“文件目录下没,其内容是: # ...
- 开始记录 Windows Phone 生涯
已经快接近三年没有更新博客了,最近打算把博客这块从新建设起来. 由于工作原因,现在已经很久没有接触过Android了.目前工作是全力 Windows Phone,并且也已经工作一年半了,以后会陆续把之 ...
- linux 开机自启动脚本
在/etc/rc.local文件中添加自启动命令(其中一种方法) 1.案例,就用博主本人之前发的博文 “nginx + flask + uwsgi + centos + python3 搭建web项目 ...
- MongoDB设置
添加mongodb用户组 groupadd mongodb 添加mongodb用户 useradd mongodb -g mongodb 将mongodb启动项目追加入rc.local保证mongod ...
- 逻辑回归&线性回归
# coding:utf-8 import numpy as np from sklearn import linear_model, datasets import matplotlib.pyplo ...
- C# 异步编程1 APM 异步程序开发
C#已有10多年历史,单从微软2年一版的更新进度来看活力异常旺盛,C#中的异步编程也经历了多个版本的演化,从今天起着手写一个系列博文,记录一下C#中的异步编程的发展历程.广告一下:喜欢我文章的朋友,请 ...
- 在ASP.NET Core中使用多环境
原文地址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-2.1#star ...
- Red5视频流服务器安装
一.安装jre JAVA运行时下载地址: https://www.java.com/zh_CN/download/manual.jsp 安装后设置环境变量,变量值是jre的安装路径 二.安装 red5 ...
- SQL like 模糊查询, in
[{"互联网":["网络媒体","微博","墨迹天气","河北天气","其他" ...
- iOS命名规范(转载)
转载地址:http://www.cnblogs.com/qiqibo/archive/2012/09/05/2671553.html 正文: • 格式化代码 ◦ 指针“*”号的位置 ▪ 如:NSStr ...