zoukankan      html  css  js  c++  java
  • BZOJ 1006 [HNOI2008]神奇的国度==最大势算法

    神奇的国度

    K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA
    相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系,是指N个人 A1A2
    ...An之间仅存在N对认识关系:(A1A2)(A2A3)...(AnA1),而没有其它认识关系.比如四边关系指ABCD四个人 AB,BC,C
    D,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)

    这个还未理解,貌似是弦图有关知识。

    根据提题意,不难看出,所有的人构成的关系图是一个弦图(长度超过 3 的环中必有一条弦),求出它的完美性消除序列,根据完美消除序列逆序贪心的染色,最终所用的色数就是本题的答案

    完美消除序列的求法:

    使用陈丹琦讲述的 MCS 法,可以在 o(n+m) 的时间复杂度中求出一个图的完美消除序列,并在 o(n+m) 的时间复杂度下判断这个完美消除序列是否合法,不过,我不知道怎么在 o(n+m) 的时间复杂度下求出这个完美消除序列,或许是利用桶优化吧,我写了个堆优化的,时间复杂度也能接受

    求完美消除序列的 MCS 法是倒着解的,也就是先求序列的第 n 个再求序列的第 n-1 个

    每次选取图中具有最大标号的点作为完美消除序列中对应位置的点,并用这个点更新所有和他邻接的不再序列中的点的标号值

    对于一个弦图的染色,用完美消除序列可以很好的解决,按照完美消除序列中的点倒着给图中的点贪心的然尽可能小的颜色

    最终,一定能够用最小的颜色数量给图中的所有点染色

    本题可以先求出来这个弦图的完美消除序列,由于一定是一个弦图,所以序列一定合法,直接根据消除序列染色就行

    更多的和弦图区间图相关的知识,请看陈丹琦的PPT:弦图与区间图

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<cstring>
     6 #define N 10007
     7 #define M 2000007
     8 using namespace std;
     9 
    10 int n,m,ans;
    11 int cnt,head[N],next[M],rea[M];
    12 int d[N],q[N],col[N],hash[N];
    13 bool vis[N];
    14 
    15 void add(int u,int v)
    16 {
    17     cnt++;
    18     next[cnt]=head[u];
    19     head[u]=cnt;
    20     rea[cnt]=v;
    21 }
    22 int main()
    23 {
    24     memset(head,-1,sizeof(head));
    25     scanf("%d%d",&n,&m);
    26     int x,y;
    27     for(int i=1;i<=m;i++)
    28     {
    29         scanf("%d%d",&x,&y);
    30         add(x,y),add(y,x);
    31     }
    32     for(int i=n;i>=1;i--)
    33     {
    34         int t=0;
    35         for(int j=1;j<=n;j++) if(!vis[j]&&d[j]>=d[t])t=j; //找未标记的度数最大的点。 
    36         vis[t]=1;q[i]=t;
    37         for(int j=head[t];j!=-1;j=next[j]) d[rea[j]]++;
    38         }
    39     for(int i=n;i>=1;i--)
    40     {
    41         int t=q[i];
    42         for(int j=head[t];j!=-1;j=next[j])
    43             hash[col[rea[j]]]=i;
    44         int j;
    45         for(j=1;j<=n;j++) 
    46             if(hash[j]!=i) break;
    47         col[t]=j;
    48         if(j>ans)ans=j;
    49     }
    50     printf("%d",ans);
    51 }
  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7632863.html
Copyright © 2011-2022 走看看