zoukankan      html  css  js  c++  java
  • BZOJ 1064 假面舞会(NOI2008) DFS判环

    此题,回想Sunshinezff学长给我们出的模拟题,原题啊有木有!!此处吐槽Sunshinezff爷出题不人道!!
    不过也感谢Sunshinezff学长的帮助,我才能做出来。。
    1064: [Noi2008]假面舞会

    Time Limit: 10 Sec Memory Limit: 162 MB
    Submit: 1262 Solved: 624
    [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,再设一个-1的边,搜一遍后,如果发现有个点被搜到了两遍,就可知是个环,否则为链,完成上述操作后就容易多了,自己编的程序可能比较低级,总是不能全A,索性对着学长的程序进行修改。。。(捂脸)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 100010
    #define M 1000010
    using namespace std;
    int n,m,x,y,p[N],fa[N],maxx[N],minn[N],point[N],next[2*M],cnt,r1,r2,ans,ans2,temp;
    bool f[N];
    struct use{int st,en,v;}e[M*2];
    int gcd(int x,int y)
    {return y==0?x:gcd(y,x%y);}
    int abs(int x)
    {if (x<0) return -x;else return x;}
    void add(int x,int y,int w){
        next[++cnt]=point[x];
        point[x]=cnt;
        e[cnt].st=x;
        e[cnt].en=y;
        e[cnt].v=w;
    }
    int find(int x)
    {if (x!=fa[x])
     fa[x]=find(fa[x]);
     return fa[x];}
    void dfs(int x){
       maxx[temp]=max(maxx[temp],p[x]);
       minn[temp]=min(minn[temp],p[x]);
       f[x]=true;
       for (int i=point[x];i;i=next[i]){
           if (!f[e[i].en])
           {p[e[i].en]=p[x]+e[i].v;
           dfs(e[i].en);}
           else
            ans=gcd(ans,abs(p[x]+e[i].v-p[e[i].en]));
        }   
    }
    int main(){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) 
        fa[i]=i;
    
        memset(minn,127/3,sizeof(minn));
        for (int i=1;i<=m;i++){
           scanf("%d%d",&x,&y);
           add(x,y,1);add(y,x,-1);
           r1=find(x);
           r2=find(y);
           if (r1!=r2) fa[r1]=r2;
        }
        for (int i=1;i<=n;i++) 
        if (!f[i])
         {temp=find(i);dfs(i);}
    
        for (int i=3;i<=ans;i++) 
        if (ans%i==0)
        {ans2=i;
        break;}
    
        if (ans2<3) 
        ans2=3;
    
        temp=0;
    
        if (ans==0) 
        for (int i=1;i<=n;i++) 
        if (i==fa[i]) 
        temp+=maxx[i]-minn[i]+1;  
    
        if (ans==0) 
        ans=temp;
    
        if (ans<3) 
        {ans=-1;
        ans2=-1;}
    
        printf("%d %d
    ",ans,ans2);
    }
    ——It's a lonely path. Don't make it any lonelier than it has to be.
  • 相关阅读:
    day 17
    day 16
    信息系统项目管理师 教程学习 第一章
    服务器安全防护
    少有人走的路
    Python文件学习
    测试新文章
    测试
    python基础 一、 数值类型、序列类型和散列类型
    apache No input filespecified
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346276.html
Copyright © 2011-2022 走看看