zoukankan      html  css  js  c++  java
  • 洛谷P1477 bzoj1064 [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。

    这道题告诉我的惨痛教训 每次挖挖之后一定要看自己空间到底开够没有!!! qswl

    这道题是一道很神奇的图论题

    首先看到这个关系首先想到把它们建边 这道题主要是分为三种情况

    1.环  2.奇奇怪怪的环  3.链

    先说说链的情况 如果有环 那么类别数会被环限制 这时候链就没用了 如果没有环 他的类别数就是所有的链长度之和 相当于把所有链的首尾连到一起

    接着是环 出现环也就是说总类别数进行了若干次循环 且一定是每个换的因子  所以最大情况数就取所有环的$gcd$即可

    最大的问题是奇奇怪怪的环 长这样子的

    因为起点相同 所以图中同种颜色的是一个类别的 那么蓝色点相当于和后面两个白点重新成环 为一个三个点的环

    所以这种情况怎么处理呢 我们建立边权为$1$的正边 $-1$的反边 那么他走一圈走回蓝点时 要继续往回走就只能走反边

    也就是说反边将类别相同的点抵消了 留下了剩余的新环 最后特判一下无解的情况即可

    代码

    #include <bits/stdc++.h>
    #define oo 1e9
    using namespace std;
    
    const int N = 1e6 + 5;
    int head[N], nex[2 * N], tov[2 * N], val[2 * N];
    int vis[N], tot, n, m, sum;
    queue<int>Q;
    vector<int>R;
    
    void add(int u, int v, int w) {
        
        tot ++;
        nex[tot] = head[u];
        tov[tot] = v;
        val[tot] = w;
        head[u] = tot;
    }
    
    void Add_Edge( ) {
        
        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);
        }
    }
    
    void bfs(int u) {
        
        vis[u] = oo; Q.push(u); bool tag = false;
        int ma = oo, mi = oo;
        while(! Q.empty( )) {
            int u = Q.front( ); Q.pop( );
            for(int i = head[u];i;i = nex[i]) {
                int v = tov[i];
                if(! vis[v]) {
                    vis[v] = vis[u] + val[i];
                    Q.push(v); 
                    ma = max(ma, vis[v]); mi = min(mi, vis[v]);
                }
                else if(vis[v] == vis[u] + val[i]) continue;
                else {
                    tag = true;
                    R.push_back(abs(vis[v] - (vis[u] + val[i])));
                }
            }
        }
        if(! tag) sum += ma - mi + 1;
    }
    
    int gcd(int a, int b) {
        
        return b == 0 ? a : gcd(b, a % b);
    }
    
    void Solve( ) {
        
        for(int i = 1; i <= n; i++) {
            if(! vis[i]) bfs(i);
        }
        if(R.size( )) {
            int ans = R[0];
            for(int i = 1;i < R.size( );i ++) {
                ans = gcd(ans, R[i]);
            }
            if(ans <= 2) {
                printf("-1 -1
    "); return ;
            }
            else {
                int anss = ans;
                for(int i = 2;i * i <= ans;i ++) {
                    if(ans % i == 0) {
                        if(i >= 3) anss = min(anss, i);
                        if(ans / i >= 3) anss = min(anss, ans / i); 
                    }
                }
                printf("%d %d
    ", ans, anss);
            }
        }
        else {
            if(sum <= 2) printf("-1 -1
    ");
            else printf("%d %d", sum, 3);
        }
    }
    
    int main( ) {
        
        Add_Edge( );
        Solve( );
    }
  • 相关阅读:
    数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号
    基于深度学习方法的dota2游戏数据分析与胜率预测(python3.6+keras框架实现)
    基于CBOW网络手动实现面向中文语料的word2vec
    《Machine Learning Yearing》读书笔记
    使用神经网络预测航班起飞准点率
    使用LSTM-RNN建立股票预测模型
    基于selenium+phantomJS的动态网站全站爬取
    TensorFlow保存、加载模型参数 | 原理描述及踩坑经验总结
    学习笔记--python中使用多进程、多线程加速文本预处理
    通过外汇对冲手段稳定获利的可行性验证
  • 原文地址:https://www.cnblogs.com/Rubenisveryhandsome/p/9776324.html
Copyright © 2011-2022 走看看