zoukankan      html  css  js  c++  java
  • BZOJ 1064[NOI2008]假面舞会

    1064: [Noi2008]假面舞会

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2044  Solved: 989
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

    包含两个数,第一个数为最大可能的面具类数,第二个数为最小可能的面具类数。如果无法将所有的面具分为至少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

    HINT

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

    有三种情况:

    1.存在链:

      那么无论答案是多少,都可以成立。

    2.有如下环:

       

      两条链的差是答案的倍数。

    3.有如下环:

       

      环上点数是答案的倍数。

    代码如下(注意abs,可能CE):

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<cmath>
     5 using namespace std;
     6 #define maxm 1000000
     7 #define maxn 100001
     8 struct node
     9 {
    10     int u,v,w,nex;
    11 }edge[maxm<<1|1];
    12 int head[maxn],cnt=1;
    13 void add(int u,int v,int w)
    14 {
    15     edge[++cnt]=(node){u,v,w,head[u]};
    16     head[u]=cnt;
    17 }
    18 int n,m,nn,mm;
    19 bool book[maxn],flag[maxm<<1];
    20 int d[maxn],ans;
    21 int gcd(int a,int b)
    22 {
    23     return b?gcd(b,a%b):a;
    24 }
    25 void dfs1(int x)
    26 {
    27     book[x]=true;
    28     for(int i=head[x];i;i=edge[i].nex)
    29     {
    30         if(!book[edge[i].v])
    31         {
    32             d[edge[i].v]=d[x]+edge[i].w;
    33             dfs1(edge[i].v);
    34         }
    35         else
    36             ans=gcd(ans,(int)abs(0.0+d[x]+edge[i].w-d[edge[i].v]));
    37     }
    38 }
    39 void dfs2(int x)
    40 {
    41     nn=min(d[x],nn);
    42     mm=max(d[x],mm);
    43     book[x]=true;
    44     for(int i=head[x];i;i=edge[i].nex)
    45         if(!flag[i])
    46         {
    47             flag[i]=flag[i^1]=true;
    48             d[edge[i].v]=d[x]+edge[i].w;
    49             dfs2(edge[i].v);
    50         }
    51 }
    52 int main()
    53 {
    54     int x,y;
    55     scanf("%d%d",&n,&m);
    56     for(int i=1;i<=m;i++)
    57     {
    58         scanf("%d%d",&x,&y);
    59         add(x,y,1);
    60         add(y,x,-1);
    61     }
    62     for(int i=1;i<=n;i++)
    63         if(!book[i])
    64             dfs1(i);
    65     if(ans)
    66     {
    67         if(ans<3)
    68             printf("%d %d",-1,-1);
    69         else
    70         {    
    71             for(x=3;x<=ans;x++)
    72                 if((ans%x)==0)
    73                     break;
    74             printf("%d %d",ans,x);
    75         }
    76         return 0;
    77     }
    78     memset(book,0,sizeof(book));
    79     for(int i=1;i<=n;i++)
    80         if(!book[i])
    81         {
    82             nn=mm=d[i]=0;
    83             dfs2(i);
    84             ans+=mm-nn+1;
    85         }
    86     if(ans>=3)
    87         printf("%d %d",ans,3);
    88     else
    89         printf("%d %d",-1,-1);
    90 }
    BZOJ 1064
  • 相关阅读:
    mybatis批量更新策略
    tk.mybatis扩展通用接口
    IDEA入门——jdbc连接和工具类的使用
    tensorflow——3
    再战tensorflow
    tensorflow初学
    Anaconda和TensorFlow安装遇到的坑记录
    《企业应用架构模式》——阅读笔记3
    机器学习十讲——第十讲
    机器学习十讲——第九讲
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7147380.html
Copyright © 2011-2022 走看看