考试的时候果断放弃,cout<<"-1 -1"骗10分hhh。。。

这也是图上问题。注意题目意思:

①如果有多个点指向同一个点,那么他们属于同一类别。

②一个点看到的所有点是一个种类。

这样的话,就可以把信息变成一堆图和一堆链。注意分情况:

①如果全是链的话,那么种类最大是他们的长度,最小理论上是多少都可以。例如1->2->3->4->5->6,可以6个种类都不同,也可能1,2,3种类不同;4,5,6种类不同,3(种类3)可以看到4(种类1),实际是一个循环,但是图中是一个链。这样种类数可以随便划分。根据题意最小就是3。

②如果有环有链,那就只需要考虑环就行了。环最大种类是环的大小,同时这个环的约数也是可以满足的

综上,总结为:

所以如果有环找出这些环,k的最大值就是这些环的大小的最大公约数。

k的最小值就是k的最大值中第一个大于等于3的约数。

如果没有环,k的最大值就是所有等价链的链长之和。最小值显然是3.

注意环的大小与方向有关,反向是-1,正向是1,最后取abs即可。

然后我们dfs每个联通块。在dfs途中对每个点标号,标号的值就是已经经过的权值和。

在dfs中如果发现某个点已经被dfs过了。说明找到一个环。

那么这个环的大小就是你将要对他标的号和他已有的标号的差的绝对值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define pos2(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
int n,m;
#define N 501000
int fa[N];
int mi[N],ma[N];
int tmp;
int abs(int x)
{
    if(x<0)
      return -x;
    return x;
}
struct haha
{
       int next,w,to;
}edge[N];
int head[N],cnt=1;
int val[N],flag[N];
int gcd(int x,int y)
{
    return y==0?x:gcd(y,x%y);
} //求最大公约数
void add(int u,int v,int w)
{
     edge[cnt].w=w;
     edge[cnt].to=v;
     edge[cnt].next=head[u];
     head[u]=cnt++;
}
int find(int x)
{
    if(x!=fa[x])
      fa[x]=find(fa[x]);
    return fa[x];
}
void he(int x,int y)
{
     int xx=find(x);
     int yy=find(y);
     if(xx!=yy)
       fa[xx]=yy;
}//并查集查找是否属于一个联通块
int ans,ans2;//最大值,最小值
void dfs(int x)
{
     ma[tmp]=max(ma[tmp],val[x]);//找连通块里面的最大值
     mi[tmp]=min(mi[tmp],val[x]); //最小值
     flag[x]=1;
     for(int i=head[x];i;i=edge[i].next)
     {
        int to=edge[i].to;
        int va=edge[i].w;
        if(!flag[to])
        {
          val[to]=val[x]+va;//记录大小
          dfs(to);
        }
        else
           ans=gcd(ans,abs(val[x]+va-val[to]));// 所有环求公约数
     }
}

int main()
{
    scanf("%d%d",&n,&m);
    memset(mi,0x3f,sizeof(mi));
    pos(i,1,n)
      fa[i]=i;
    pos(i,1,m)
    {
       int x,y;
       scanf("%d%d",&x,&y);
       add(x,y,1);
       add(y,x,-1);
       he(x,y);
    }
    pos(i,1,n)
      if(!flag[i])
      {
         tmp=find(i);
         dfs(i);
      }
    pos(i,3,ans)
      if(ans%i==0)
      {
        ans2=i;//大于三的最小公约数
        break;
      }
    ans2=max(3,ans2);
    int sum=0;
    if(ans==0)
    {
       pos(i,1,n)
         if(i==fa[i])
           sum+=ma[i]-mi[i]+1;//是链最大是总和
       ans=sum;
    }
    if(ans<3)
      ans=ans2=-1;
    printf("%d %d\n",ans,ans2);
    while(1);
    return 0;
}

  

[Noi2008]假面舞会的更多相关文章

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

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

  2. [BZOJ1064][Noi2008]假面舞会

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

  3. NOI2008假面舞会

    1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 883  Solved: 462[Submit][Status] ...

  4. 【洛谷】1477:[NOI2008]假面舞会【图论】

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

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

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

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

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

  7. 1064: [Noi2008]假面舞会 - BZOJ

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

  8. 【BZOJ】1064: [Noi2008]假面舞会(判环+gcd+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1064 表示想到某一种情况就不敢写下去了.... 就是找环的gcd...好可怕.. 于是膜拜了题解.. ...

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

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

  10. BZOJ1064 [Noi2008]假面舞会 【dfs】

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

随机推荐

  1. golang中defer的使用规则

    转自个人博客chinazt.cc 在golang当中,defer代码块会在函数调用链表中增加一个函数调用.这个函数调用不是普通的函数调用,而是会在函数正常返回,也就是return之后添加一个函数调用. ...

  2. Ext template 的使用

    Ext template 的使用 Ext.define('app.view.MyDataView', { extend: 'Ext.panel.Panel', xtype: 'myDataView', ...

  3. [Android FrameWork 6.0源码学习] View的重绘过程

    View绘制的三部曲,  测量,布局,绘画今天我们分析测量过程 view的测量是从ViewRootImpl发起的,View需要重绘,都是发送请求给ViewRootImpl,然后他组织重绘在重绘的过程中 ...

  4. JAVAEE——SSH项目实战01:SVN介绍、安装和使用方法

    1 学习目标 1.掌握svn服务端.svn客户端.svn eclipse插件安装方法 2.掌握svn的基本使用方法 2 svn介绍 2.1 项目管理中的版本控制问题 通常软件开发由多人协作开发,如果对 ...

  5. Vijos 1006 晴天小猪历险记之Hill 单源单汇最短路

    背景 在很久很久以前,有一个动物村庄,那里是猪的乐园(^_^),村民们勤劳.勇敢.善良.团结-- 不过有一天,最小的小小猪生病了,而这种病是极其罕见的,因此大家都没有储存这种药物.所以晴天小猪自告奋勇 ...

  6. ExtJs2.0里Ext.form.Radio水平排列布局

      ExtJs2.0好像不支持单选框组,因此用两个name相同单选框来实现单选框组 var radio1 = new Ext.form.Radio({boxLabel:'男',name:'sex',i ...

  7. JanaScript预解析

    JS预解析是什么?      在当前的作用域下,js运行之前.会有带有 var 和 function关键字的代码事先声明,      并在内存中安排好,然后从上到下的执行js代码. JS预解析 js逐 ...

  8. HDU 1051 Wooden Sticks 贪心||DP

    Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  9. [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增

    Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...

  10. CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)

    CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...