首先,可以把每个人看成一个点,能看见谁就相当于两个人之间有一个单向边,这样就可以把关系看成几个连通图。

对于每个连通图,有三种情况:

1.所有边数之和的最大公约数

2.正向边和反向边差的绝对值的最大公约数

3.是一条链

记录的时候可以把正向边记为+1,反向边记为-1,遍历的时候只要记录图中的加和 就可以得知前两种情况,然后取gcd就是max,min是最小的、大于3的、max的约数。

如果在最后没有找到环,说明只有链能限制,这时就算出每个连通图中最长链,然后加和为max,min就是3了。

而如果有环,那么只能按环算,因为链无论如何也能满足,而环不行。

最后附上代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int read()
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int read()
{
int ans=0;char q=getchar();
while(q<'0'||q>'9')q=getchar();
while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
return ans;
}
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
int abss(int x){return x<0?-x:x;}
int maxn(int a,int b){return a>b?a:b;}
int minn(int a,int b){return a<b?a:b;}
struct son
{
int v,next,w;
};
son a1[6000001];
int first[6000001],e;void addbian(int u,int v,int w)
{
a1[e].w=w;
a1[e].v=v;
a1[e].next=first[u];
first[u]=e++;
}int n,m,u,o;
int vis[600001];
int ans;
int w[600001];
int maxl,minl;void dfs(int fa,int x,int val)
{
vis[x]=1;
w[x]=val;
for(int i=first[x];i!=-1;i=a1[i].next)
{
int temp=a1[i].v;
if(temp==fa)continue;
if(vis[temp])
{
if(val==0)continue;
ans=gcd(ans,abss(val+a1[i].w-w[temp]));
continue;
}
dfs(x,temp,val+a1[i].w);
}
}void dfs2(int fa,int x,int val)
{
vis[x]=1;
maxl=maxn(maxl,val);
minl=minn(minl,val);
for(int i=first[x];i!=-1;i=a1[i].next)
{
int temp=a1[i].v;
if(vis[temp]||temp==fa)continue;
dfs2(x,temp,val+a1[i].w);
}
}int main(){
mem(first,-1);
n=read();m=read();
for(int i=1;i<=m;++i)
{
u=read();o=read();
addbian(u,o,1);
addbian(o,u,-1);
}
for(int i=1;i<=n;++i)
{
if(vis[i])continue;
dfs(-1,i,0);
}if(ans)
{
if(ans<3)printf("-1 -1");
else
{
printf("%d ",ans);
for(int i=3;i<=ans;++i)if(!(ans%i)){printf("%d",i);
break;
}
}
}
else
{
mem(vis,0);
for(int i=1;i<=n;++i)
{
if(vis[i])continue;
printf("i=%d\n",i);
maxl=minl=0;
dfs2(-1,i,0);
ans+=(maxl-minl+1);
}
if(ans<3)printf("-1 -1");
elseprintf("%d 3",ans);
}
while(1);
return 0;
}
{int ans=0;char q=getchar();while(q<'0'||q>'9')q=getchar();while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}return ans;}int gcd(int x,int y){return y==0?x:gcd(y,x%y);}int abss(int x){return x<0?-x:x;}int maxn(int a,int b){return a>b?a:b;}int minn(int a,int
b){return a<b?a:b;}struct son{int v,next,w;};son a1[6000001];int first[6000001],e;void addbian(int u,int v,int w){a1[e].w=w;a1[e].v=v;a1[e].next=first[u];first[u]=e++;}int n,m,u,o;int vis[600001];int ans;int w[600001];int maxl,minl;void dfs(int fa,int x,int
val){vis[x]=1;w[x]=val;for(int i=first[x];i!=-1;i=a1[i].next){int temp=a1[i].v;if(temp==fa)continue;if(vis[temp]){if(val==0)continue;ans=gcd(ans,abss(val+a1[i].w-w[temp]));continue;}dfs(x,temp,val+a1[i].w);}}void dfs2(int fa,int x,int val){vis[x]=1;maxl=maxn(maxl,val);minl=minn(minl,val);for(int
i=first[x];i!=-1;i=a1[i].next){int temp=a1[i].v;if(vis[temp]||temp==fa)continue;dfs2(x,temp,val+a1[i].w);}}int main(){mem(first,-1);n=read();m=read();for(int i=1;i<=m;++i){u=read();o=read();addbian(u,o,1);addbian(o,u,-1);}for(int i=1;i<=n;++i){if(vis[i])continue;dfs(-1,i,0);}if(ans){if(ans<3)
printf("-1 -1");else{printf("%d ",ans);for(int i=3;i<=ans;++i) if(!(ans%i)) { printf("%d",i);break;}}}else{mem(vis,0);for(int i=1;i<=n;++i){if(vis[i])continue;printf("i=%d\n",i);maxl=minl=0;dfs2(-1,i,0);ans+=(maxl-minl+1);}if(ans<3) printf("-1 -1");else printf("%d
3",ans);}while(1);return 0;}
												

2017.7.10 noi2008 假面舞会相关推荐

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

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

  2. 【做题记录】[NOI2008] 假面舞会—有向图上的环与最长链

    luogu 1477 [NOI2008] 假面舞会 容易发现: 如果图中没有环,那么面具种数一定是所有联通块内最长链之和,最少为 \(3\) . 如果有环,则面具种数一定是所有环的大小的最大公约数. ...

  3. bzoj 1064: [Noi2008]假面舞会(DFS)

    1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2240  Solved: 1083 [Submit][Sta ...

  4. [BZOJ]1064 [NOI2008] 假面舞会 dfs判环

    1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2160  Solved: 1047 [Submit][Sta ...

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

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

  6. 1064: [Noi2008]假面舞会

    1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1960  Solved: 941 [Submit][Stat ...

  7. [Noi2008]假面舞会(dfs判环)

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

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

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

  9. 洛谷 P1477 [NOI2008]假面舞会

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

最新文章

  1. 10013: An attempt was made to access a socket in a way forbidden by its access permissions
  2. Spring5 新增的两大功能,吹一波这个框架!
  3. Linux设置环境变量小结:设置永久变量临时变量 全局变量局部变量
  4. 平凡的故事:年轻开发者的那些伤心事
  5. K-special Tables
  6. MyBatis的四种资源加载方式以及优先级
  7. 计算机维修万用电表使用,万用表的使用方法——图解
  8. 华为手机鸿蒙系统卡吗,华为鸿蒙系统能解决手机卡顿吗 华为鸿蒙系统会不会卡顿...
  9. Flowable工作流引擎表用途整理
  10. 2019全国大学生信息安全竞赛—Web
  11. 利用镜像解决一系列下载速度慢的问题
  12. python语音识别依赖包
  13. python基础(一):python简介
  14. ANTLR4 入门学习(一):下载和测试
  15. Java类与对象案例之打字游戏
  16. -bash: mysql: command not found 解决办法
  17. 2019年新SRRC认证怎么收费
  18. ccs matlab联调,超详细干货:matlab2017a与 CCS 6.2联调设置
  19. MPC控制器设计,模型预测控制,线性时变模型预测控制,LTV MPC,提供理论讲解与应用实现
  20. ArrayList集合的常用方法

热门文章

  1. 台式计算机系统重新安装软件,教你台式机如何重装系统
  2. GPT分区系统硬盘对拷后系统无法启动
  3. 刚入行的 可以了解下什么是物理机和虚拟机 租用和托管 ——世通兰陵王为你解答
  4. AngularJs搭配Bootstrap-select的防坑指南
  5. C++新特性——郭炜
  6. 小米4c手机显示无服务器,小米4C卡机怎么办 小米4C卡机解决办法【图文】
  7. android 替换全局字体
  8. long 雪花算法_小飞
  9. 文华编程是c 语言吗,文华财经编程规则
  10. 郑州机电工程学校计算机部,郑州机电工程学校