1800 假面舞会

1800 假面舞会

2008年NOI全国竞赛

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 大师 Master

题解

查看运行结果

题目描述 Description

一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会。 今年的面具都是主办方特别定制的。每个参加舞会的人都可以在入场时选择 一个自己喜欢的面具。每个面具都有一个编号,主办方会把此编号告诉拿该面具 的人。 为了使舞会更有神秘感,主办方把面具分为 k (k≥3)类,并使用特殊的技术将 每个面具的编号标在了面具上,只有戴第 i 类面具的人才能看到戴第 i+1 类面具 的人的编号,戴第 k 类面具的人能看到戴第 1 类面具的人的编号。 参加舞会的人并不知道有多少类面具,但是栋栋对此却特别好奇,他想自己 算出有多少类面具,于是他开始在人群中收集信息。 栋栋收集的信息都是戴第几号面具的人看到了第几号面具的编号。如戴第 2 号面具的人看到了第 5 号面具的编号。栋栋自己也会看到一些编号,他也会根据 自己的面具编号把信息补充进去。 由于并不是每个人都能记住自己所看到的全部编号,因此,栋栋收集的信息 不能保证其完整性。现在请你计算,按照栋栋目前得到的信息,至多和至少有多 少类面具。由于主办方已经声明了 k≥3,所以你必须将这条信息也考虑进去。

输入描述 Input Description

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

输出描述 Output Description

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

样例输入 Sample Input

【输入样例一】 
6 5 1 2 2 3 3 4 4 1 3 5 
【输入样例二】 
3 3 1 2 2 1 2 3

样例输出 Sample Output

【输出样例一】 
4 4 
【输出样例二】 
-1 -1

数据范围及提示 Data Size & Hint

50%的数据,满足 n ≤ 300, m ≤ 1000;

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

分类标签 Tags 点此展开

大陆地区 NOI全国竞赛 2008年

题解:

1、当图中有环时,k必定是环长度的约数,那么答案就是全部环的最大公约数和最小的大于3的公约数,若最大公约数小于3则无解;

当图中没有环时,k最大就是所有联通块最长链的和
2、实现时,所有边建长度为1的正向边和长度为-1的反向边,会容易处理很多

AC代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
const int N=2e5+10;
const int M=2e6+10;
int n,m,ans1,ans2,mi,ma,tot,d[N],v[M],w[M],next[M],head[M];
bool vis[N];
inline int read(){
    register int x=0,f=1;
    register char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
void add(int x,int y,int z){
    v[++tot]=y;w[tot]=z;next[tot]=head[x];head[x]=tot;
}
int gcd(int a,int b){
    return !b?a:gcd(b,a%b);
}
void tarjan(int x){//判断是否有环
    vis[x]=1;
    for(int i=head[x];i;i=next[i])
        if(vis[v[i]]) ans1=gcd(ans1,abs(d[x]+w[i]-d[v[i]]));
        else d[v[i]]=d[x]+w[i],tarjan(v[i]);
}
void dfs(int x){
    vis[x]=1;
    ma=max(ma,d[x]),mi=min(mi,d[x]);
    for(int i=head[x];i;i=next[i])
        if(!vis[v[i]]) d[v[i]]=d[x]+w[i],dfs(v[i]);
}
int main(){
    n=read();m=read();
    for(int i=1,a,b;i<=m;i++) a=read(),b=read(),add(a,b,1),add(b,a,-1);
    for(int i=1;i<=n;i++) if(!vis[i]) tarjan(i);
    if(ans1) for(ans2=3;ans2<ans1&&ans1%ans2;ans2++);//有环
    else{//无环
        memset(vis,0,sizeof vis);
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                ma=mi=d[i]=0;
                dfs(i);
                ans1+=ma-mi+1;
            }
        }
        ans2=3;
    }
    if(ans1<3) ans1=ans2=-1;
    printf("%d %d\n",ans1,ans2);
    return 0;
} 
时间: 2024-11-07 05:25:22

1800 假面舞会的相关文章

假面舞会(codevs 1800)

题目描述 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择 一个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具 的人. 为了使舞会更有神秘感,主办方把面具分为 k (k≥3)类,并使用特殊的技术将 每个面具的编号标在了面具上,只有戴第 i 类面具的人才能看到戴第 i+1 类面具 的人的编号,戴第 k 类面具的人能看到戴第 1 类面具的人的编号. 参加舞会的人并不知道有多少

[BZOJ1064][Noi2008]假面舞会

试题描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特殊的技术将每个面具的编号标在了面具上,只有戴第i 类面具的人才能看到戴第i+1 类面具的人的编号,戴第k 类面具的人能看到戴第1 类面具的人的编号. 参加舞会的人并不知道有多少类面具,但是栋栋对此却特别好奇,他想自己算出

BZOJ 1064 假面舞会(图论-连通分量)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1064 题意:一年一度的假面舞会又开始了,栋栋也 兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特殊的技术将每个面具的编号标在了面具上,只有戴第i 类面具的人才能看到戴第i+1 类面具的人的编号,戴第k

BZOJ 1064[NOI2008]假面舞会

1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2044  Solved: 989[Submit][Status][Discuss] Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为k (k≥

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

BZOJ 1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1655  Solved: 798[Submit][Status][Discuss] Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为

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

http://www.lydsy.com/JudgeOnline/problem.php?id=1064 表示想到某一种情况就不敢写下去了.... 就是找环的gcd...好可怕.. 于是膜拜了题解.. 和我想的差不多.. 首先发现这3几种情况: 1.一条或多条单链,那么最多有sum{单链长度}个面具,最少有3个面具 2.环.主要是大环套小环QAQ,显然我们只要小环就行了QAQ环的长度为标号差,gcd能满足这个性质,因此不管它.找出所有的环即可. 3.链相交.此时最大为相交链的长度差的gcd,最小

【BZOJ 1064】 [Noi2008]假面舞会

1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 988  Solved: 507 [Submit][Status] Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特

NOI2008假面舞会

1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 883  Solved: 462[Submit][Status] Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特殊的

NOI 2008 假面舞会

题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人. 为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特殊的技术将每个面具的编号标在了面具上,只有戴第i 类面具的人才能看到戴第i+1 类面具的人的编号,戴第k 类面具的人能看到戴第1 类面具的人的编号. 参加舞会的人并不知道有多少类面具,但是栋栋对此却特别好奇,他想自己