zoukankan      html  css  js  c++  java
  • [BZOJ1006] [HNOI2008] 神奇的国度 (弦图)

    Description

      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) 

    Source

    Solution

      cdq《弦图与区间图》论文题

      题意保证图为弦图,然后本题又是求最小染色,于是用$MCS$算法求一个完美消除序列,倒着贪心即可,论文里有说明

      原论文里使用了桶排序使得其为$O(n+m)$,蒟蒻智商余额不足表示看不懂,于是用的优先队列,大概是$O((n+m)log(n+m))$

      (咦好多人都是$O(n^2+m)$的?啊不怕不怕啦!)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct edge
     4 {
     5     int v, nxt;
     6 }e[2000005];
     7 int fst[10005], label[10005], s[10005], vis[10005];
     8 priority_queue<pair<int, int> > PQ;
     9  
    10 void addedge(int i, int u, int v)
    11 {
    12     e[i] = (edge){v, fst[u]}, fst[u] = i;
    13 }
    14  
    15 int main()
    16 {
    17     int n, m, u, v, ans = 0;
    18     scanf("%d%d", &n, &m);
    19     for(int i = 1; i <= m; ++i)
    20     {
    21         scanf("%d%d", &u, &v);
    22         addedge(i << 1, u, v);
    23         addedge(i << 1 | 1, v, u);
    24     }
    25     for(int i = 1; i <= n; ++i)
    26         PQ.push(make_pair(0, i));
    27     for(int i = n; i; --i)
    28     {
    29         u = PQ.top().second, PQ.pop();
    30         while(vis[u])
    31             u = PQ.top().second, PQ.pop();
    32         s[i] = u, vis[u] = -1;
    33         for(int j = fst[u]; j; j = e[j].nxt)
    34         {
    35             v = e[j].v;
    36             if(vis[v]) continue;
    37             PQ.push(make_pair(++label[v], v));
    38         }
    39     }
    40     memset(label, 0, sizeof(label));
    41     for(int i = n; i; --i)
    42     {
    43         for(int j = fst[s[i]]; j; j = e[j].nxt)
    44             vis[label[e[j].v]] = i;
    45         for(int j = 1; ; ++j)
    46             if(vis[j] != i)
    47             {
    48                 label[s[i]] = j, ans = max(ans, j);
    49                 break;
    50             }
    51     }
    52     printf("%d
    ", ans);
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    华为 p8上配置outllook,同步日历/邮件
    tgz 文件解压
    9 Essential Free Linux Transcoders(转码)
    mini2440移植uboot 2014.04(七)
    uboot无法引导uImage错误及其解决方法
    mini2440移植uboot 2014.04(六)
    mini2440移植uboot 2014.04(五)
    debian内核代码执行流程(三)
    debian内核代码执行流程(二)
    linux usb简介
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5668664.html
Copyright © 2011-2022 走看看