• BZOJ 1006 神奇的国度


    Description

    K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系,是指N个人 A1A2...An之间仅存在N对认识关系:(A1A2)(A2A3)...(AnA1),而没有其它认识关系.比如四边关系指ABCD四个人 AB,BC,CD,DA相互认识,而AC,BD不认识.全民比赛时,为了防止做弊,规定任意一对相互认识的人不得在一队,国王相知道,最少可以分多少支队。

    Input

    第一行两个整数N,M。1<=N<=10000,1<=M<=1000000.表示有N个人,M对认识关系. 接下来M行每行输入一对朋友

    Output

    输出一个整数,最少可以分多少队

    Sample Input

    4 5
    1 2
    1 4
    2 4
    2 3
    3 4

    Sample Output

    3

    HINT

    一种方案(1,3)(2)(4)

    Source

    鬼畜的论文题,参见cdq的论文《区间图与弦图》。

    先利用mcs最大势算法求完美消除序列(cdq说复杂度是线性的,可是我始终还是得带个log),再根据完美消除序列进行染色即可。

    代码如下:

     1 #include<algorithm>
     2 #include<queue>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<set>
     6 using namespace std;
     7 
     8 #define maxn 10010
     9 #define maxc 510
    10 #define maxm 1000010
    11 int tot,n,m,cnt,color[maxn][maxc],label[maxn],all;
    12 int side[maxn],next[maxm*2],toit[maxm*2],per[maxn];
    13 bool in[maxn];
    14 struct node
    15 {
    16     int key,ord;
    17     friend bool operator < (node a,node b) {return a.key > b.key; }
    18 };
    19 multiset <node> S;
    20 
    21 inline void add(int a,int b)
    22 {
    23     next[++cnt] = side[a]; side[a] = cnt; toit[cnt] = b; 
    24 }
    25 
    26 inline void ins(int a,int b){add(a,b); add(b,a);}
    27 
    28 inline void mcs()
    29 {
    30     int i,u;
    31     for (i = 1;i <= n;++i) S.insert((node){0,i});
    32     while (all < n)
    33     {
    34         u = (*S.begin()).ord; S.erase(S.begin()); if (in[u]) continue;
    35         in[u] = true; per[++all] = u;
    36         for (i = side[u];i;i = next[i])
    37             if (!in[toit[i]])
    38             {
    39                 label[toit[i]]++;
    40                 S.insert((node){label[toit[i]],toit[i]});
    41             }
    42     }
    43 }
    44 
    45 inline void paint()
    46 {
    47     int p,i,j,t;
    48     for (p = 1;p <= n;++p)
    49     {
    50         i = per[p];
    51         for (j = 1;j <= tot;++j)
    52             if (!color[i][j]) {t = j; break; }
    53         if (j == tot + 1) t = ++tot;
    54         for (j = side[i];j;j = next[j])
    55             color[toit[j]][t] = true;
    56     }
    57 }
    58 
    59 int main()
    60 {
    61     freopen("1006.in","r",stdin);
    62     freopen("1006.out","w",stdout);
    63     scanf("%d %d",&n,&m);
    64     for (int i = 1;i <= m;++i)
    65     { int a,b; scanf("%d %d",&a,&b); ins(a,b); }
    66     mcs();
    67     paint();
    68     printf("%d",tot);
    69     fclose(stdin); fclose(stdout);
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    如何成为一名专家级的开发人员
    ZapThink探讨未来十年中企业IT的若干趋势
    Adobe CTO:Android将超预期获50%份额
    我的美国之行
    用上Vista了!
    用pylint来检查python程序的潜在错误
    delegate in c++ (new version)
    The GNU Text Utilities
    python程序转为exe文件
    c++头文件,cpp文件,makefile,unit test自动生成器
  • 原文地址:https://www.cnblogs.com/mmlz/p/4226061.html
Copyright © 2020-2023  润新知