• [NOI2008]假面舞会(DFS)


    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
     

    解题思路:

    原谅我过于蒟蒻。

    这道题就是一个深搜。

    问题就在于,如果这个图是完整的,也就是说没有残缺,那么一定整体上是一个大环。

    我们称之为骨架。

    我们的任务就是找出这个骨架的长度。

    那么比较好办的是如果给你一条链,那么可能的答案就是3~链长的所有解。

    如果给你一个环,那么答案就是所有环长约数的环。

    弄清楚这个以后,我们就可以找环了。

    首先,化有向变无向,出始深度为0,反边权为-1。

    对于无向图建dfs树,如果存在环的话直接更新答案。

    在dfs的过程中记录出现的最大和最小深度。

    用三个变量来存。

    链长即max-min+1

    最后讨论一下是否有环即可。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using std::min;
      5 using std::max;
      6 using std::sort;
      7 using std::abs;
      8 void ade(int f,int t,int v);
      9 struct ed{
     10     int f;
     11     int t;
     12     void Insert(void)
     13     {
     14         scanf("%d%d",&f,&t);
     15         return ;
     16     }
     17     void add(void)
     18     {
     19         ade(f,t,1);
     20         ade(t,f,-1);
     21         return ;
     22     }
     23     bool friend operator != (ed x,ed y)
     24     {
     25         return (x.f!=y.f)||(x.t!=y.t);
     26     }
     27 }edde[1000005];
     28 struct pnt{
     29     int hd;
     30     int dp;
     31     bool vis;
     32 }p[500000];
     33 struct ent{
     34     int twd;
     35     int lst;
     36     int vls;
     37 }e[3000000];
     38 int cnt;
     39 int n,m;
     40 int ansmin,ansmax;
     41 int cha;
     42 int Uns;
     43 void ade(int f,int t,int v)
     44 {
     45     cnt++;
     46     e[cnt].twd=t;
     47     e[cnt].lst=p[f].hd;
     48     e[cnt].vls=v;
     49     p[f].hd=cnt;
     50 }
     51 bool cmp(ed x,ed y)
     52 {
     53     if(x.f==y.f)
     54         return x.t<y.t;
     55     return x.f<y.f;
     56 }   
     57 int gcd(int x,int y)
     58 {   
     59     return (!y)?x:gcd(y,x%y);
     60 }
     61 void dfs(int x,int dep)
     62 {
     63     p[x].vis=true;
     64     p[x].dp=dep;
     65     ansmin=min(ansmin,dep);
     66     ansmax=max(ansmax,dep);
     67     for(int i=p[x].hd;i;i=e[i].lst)
     68     {
     69         int to=e[i].twd;
     70         if(p[to].vis)
     71         {
     72             Uns=gcd(abs(p[to].dp-dep-e[i].vls),Uns);
     73         }else{
     74             dfs(to,dep+e[i].vls);
     75         }
     76     }
     77     return ;
     78 }
     79 int main(void)
     80 {
     81     scanf("%d%d",&n,&m);
     82     for(int i=1;i<=m;i++)
     83         edde[i].Insert();
     84     sort(edde+1,edde+m+1,cmp);
     85     edde[1].add();
     86     for(int i=2;i<=m;i++)
     87         if(edde[i]!=edde[i-1])
     88             edde[i].add();
     89     for(int i=1;i<=n;i++)
     90     {
     91         if(!p[i].vis)
     92         {
     93             ansmax=ansmin=0;
     94             dfs(i,0);
     95             cha+=ansmax-ansmin+1;
     96         }
     97     }
     98     if(Uns>=3)
     99     {
    100         for(int i=3;i<=Uns;i++)
    101         {
    102             if(Uns%i==0)
    103             {
    104                 printf("%d %d
    ",Uns,i);
    105                 return 0;
    106             }
    107         }
    108         printf("%d %d",Uns,Uns);
    109     }else{
    110         if(Uns==0&&cha>=3)
    111         {
    112             printf("%d %d
    ",cha,3);
    113             return 0;
    114         }
    115         printf("-1 -1
    ");
    116     }
    117     return 0;
    118 }
  • 相关阅读:
    代理类和装饰类的区别
    spring mvc 处理映射的几种方式
    如何深入浅出的理解跳转方式:重定向和请求转发
    springMVC拦截配置
    ※版本管理※=>☆SVN工具=>※解决地域麻烦※№→搭建自己的网络SVN (SourceForge 免费) [转]
    权力社会? 金钱社会? 透过现象看本质-让权力和金钱的力量沿着制度的河道流淌,才是社会稳定的基石
    自己封装的CMusic类 【转】
    VC++中MCI播放音频文件 【转】
    DevExpress.XtraGrid 【转】
    C# Process.Start()方法详解 [转]
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9624730.html
Copyright © 2020-2023  润新知