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


    P1477 [NOI2008]假面舞会

    题目描述

    一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会。

    今年的面具都是主办方特别定制的。每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具。每个面具都有一个编号,主办方会把此编号告诉拿该面具的人。

    为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特殊的技术将每个面具的编号标在了面具上,只有戴第i 类面具的人才能看到戴第i+1 类面具的人的编号,戴第k 类面具的人能看到戴第1 类面具的人的编号。

    参加舞会的人并不知道有多少类面具,但是栋栋对此却特别好奇,他想自己算出有多少类面具,于是他开始在人群中收集信息。

    栋栋收集的信息都是戴第几号面具的人看到了第几号面具的编号。如戴第2号面具的人看到了第5 号面具的编号。栋栋自己也会看到一些编号,他也会根据自己的面具编号把信息补充进去。

    由于并不是每个人都能记住自己所看到的全部编号,因此,栋栋收集的信 息不能保证其完整性。现在请你计算,按照栋栋目前得到的信息,至多和至少有多少类面具。由于主办方已经声明了k≥3,所以你必须将这条信息也考虑进去。

    输入输出格式

    输入格式:

     

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

     

    输出格式:

     

    包含两个数,第一个数为最大可能的面具类数,第二个数为最小可能的面具类数。如果无法将所有的面具分为至少3 类,使得这些信息都满足,则认为栋栋收集的信息有错误,输出两个-1。

    输入输出样例

    输入样例#1: 复制
    6 5
    1 2
    2 3
    3 4
    4 1
    3 5
    输出样例#1: 复制
    4 4
    
    输入样例#2: 复制
    3 3
    1 2
    2 1
    2 3
    输出样例#2: 复制
    -1 -1
    

    说明

    50%的数据,满足n ≤ 300, m ≤ 1000;

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


    Solution

    有思维难度而没有算法难度的奇奇怪怪的图论题==

    分情况讨论八。

    如果只有环的情况,明显就是所有环的长度取gcd是种类的最大值。如果又有环又有链,链实际上没用,只用判环就好。如果只有链,那么把所有链拼到一起,总长度就是种类数的最大值,最小值就是3-ans能被ans整除的最小值。

    关于环,如果建出来的正图没有环,但是变成无向图是有环,如何去判断?就建反边,正边权为1,反边权为-1,正常跑dfs判环就可以叻。

    【注意】环长度每次是取绝对值!!!(有可能是负的减正的)

    还有一个有趣的事实:任何数和0取gcd结果都是它本身!!

    Code

    #include<bits/stdc++.h>
    using namespace std;
    
    int n, m;
    
    struct Node {
        int v, nex, w;
        Node(int v = 0, int nex = 0, int w = 0) :
            v(v), nex(nex), w(w) { }
    } Edge[2000005];
    
    int h[100005], stot;
    void add(int u, int v, int d) {
        Edge[++stot] = Node(v, h[u], d);
        h[u] = stot;
    }
    
    int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    
    int vis[100005], dep[1000005], ans, len, lenmi, lenma;
    void dfs(int u, int deep) {
        if(!vis[u]) {
            vis[u] = 1;
            dep[u] = deep;
            lenmi = min(lenmi, deep);
            lenma = max(lenma, deep);
            for(int i = h[u]; i; i = Edge[i].nex) {
                int v = Edge[i].v;
                dfs(v, deep + Edge[i].w);
            }
        } else ans = gcd(ans, abs(deep - dep[u]));
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; i ++) {
            int u, v;
            scanf("%d%d", &u, &v);
            add(u, v, 1); add(v, u, -1);
        }
        for(int i = 1; i <= n; i ++)
            if(!vis[i])    {
                dfs(i, 0);
                len += lenma - lenmi + 1;
                lenmi = lenma = 0;
            }
        if(ans >= 3) {
            for(int i = 3; i <= ans; i ++)
                if(ans % i == 0) {
                    printf("%d %d", ans, i);
                    break;
                }
        } else if(ans == 0 && len >= 3)    printf("%d 3", len);
        else printf("-1 -1");
        return 0;
    }
  • 相关阅读:
    jQuery插件:用于获取元素自身的HTML内容
    自定义 Web 部件用户界面简介
    在MOSS2010中实现OU下的用户的上下级组织关系
    sharepoint2010人性化的地方--员工离职AD账号禁用(个人网站自动提醒上级经理功能)
    SharePoint2010文档归档策略(2)-从放置库转移到自己定义的文档库
    SharePoint2010文档归档策略
    如何用VS2010在SharePoint中创建自定义字段类型(以eWebEditor为例)
    如何实现SP文档库类似百度文档库的效果 (副标题:如何在SP2013文档库的SWF文件用FlexPager显示)
    查看SharePoint文档库是,显示层次目录,可以点击返回层次
    安装和配置SharePoint 2013 with SP1 Workflow
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9776235.html
Copyright © 2020-2023  润新知