BZOJ 1064 假面舞会

http://www.lydsy.com/JudgeOnline/problem.php?id=1064

思路:第一眼看的时候以为是差分约束,但是是做不了的,不过能保证的就是这题绝对是图论题。。。(废话)

分联通块考虑,如果每个联通块都是没有有向环的话,那么各个联通块中,最长链就是最大答案,3就是最小答案。

只要有一个联通块有环,那么答案一定是这个环长度的因数,最大答案,就是这些环长度的gcd

不过,要是有这个非正常的环怎么办?

我们可以看到,4->3和2->3都指向了3,这怎么办?那么我们只要在一开始建图的时候,原来的有向边权值为1,再同时建一个反向边权值为-1,把有向图变成无向图。

为什么?,因为如图,4可以到3,2也可以到3,说明2的编号和4相同,所以2->3->4的路径实际上是"走出去一步,又走回来一步",也就是我常说的"有来有回",按照我们刚才的建图方式,这个环的长度就是:1+1+1+1-1=3,事实上,答案也是如此,3和5编号相同,2和4编号相同,这样图中实际上是只有3种面具。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 int tot,go[2100005],next[2100005],first[2100005];
 7 int c[200005],dis[200005],vis[200005],n,m,len,val[2100005];
 8 int read(){
 9     int t=0,f=1;char ch=getchar();
10     while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-1;ch=getchar();}
11     while (‘0‘<=ch&&ch<=‘9‘){t=t*10+ch-‘0‘;ch=getchar();}
12     return t*f;
13 }
14 void insert(int x,int y,int z){
15     tot++;
16     go[tot]=y;
17     next[tot]=first[x];
18     first[x]=tot;
19     val[tot]=z;
20 }
21 void add(int x,int y){
22     insert(x,y,1);insert(y,x,-1);
23 }
24 int gcd(int a,int b){
25     if (b==0) return a;
26     else return gcd(b,a%b);
27 }
28 int bfs(int x){
29     int h=1,t=1;c[1]=x;vis[x]=1;dis[x]=0;
30     int mxdis=0,mndis=0;
31     while (h<=t){
32         int now=c[h++];
33         for (int i=first[now];i;i=next[i]){
34             int pur=go[i];
35             if (vis[pur]){
36                 len=gcd(len,val[i]+dis[now]-dis[pur]);
37                 continue;
38             }
39             vis[pur]=1;
40             c[++t]=pur;
41             dis[pur]=dis[now]+val[i];
42             mxdis=std::max(mxdis,dis[pur]);
43             mndis=std::min(mndis,dis[pur]);
44         }
45     }
46     return mxdis-mndis+1;
47 }
48 int main(){
49     n=read();m=read();
50     for (int i=1;i<=m;i++){
51         int x=read(),y=read();
52         add(x,y);
53     }
54     int sum=0;
55     for (int i=1;i<=n;i++)
56      if (!vis[i]) sum+=bfs(i);
57     len=std::abs(len);
58     if (len){
59         if (len<3) {
60             printf("-1 -1\n");
61             return 0;
62         }
63         printf("%d ",len);
64         for (int i=3;i<=len;i++)
65          if (len%i==0) {
66                 printf("%d\n",i);
67                 break;
68          }
69         return 0;
70     }else
71     if (sum<3){
72         printf("-1 -1\n");
73         return 0;
74     }else{
75         printf("%d 3\n",sum);
76         return 0;
77     }
78 }
时间: 2024-08-06 06:10:25

BZOJ 1064 假面舞会的相关文章

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

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

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

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

BZOJ 1064[NOI2008]假面舞会

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

【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)类,并使用特殊的

[BZOJ1064][Noi2008]假面舞会

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

假面舞会(codevs 1800)

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

1800 假面舞会

1800 假面舞会 2008年NOI全国竞赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 查看运行结果 题目描述 Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择 一个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具 的人. 为了使舞会更有神秘感,主办方把面具分为 k (k≥3)类,并使用特殊的技术将 每个面具的编号标在了面具