bzoj1006_chord diagram minimum point coloring

Description

Country K is a country that is keen on triangles, and even people only like the principle of triangles. They believe that triangular relationships: that is, AB knows each other, BC knows each other, and CA knows each other, which is simple and efficient. The existence of four-sided relationship, five-sided relationship, etc. The so-called N-sided relationship means that there are only N pairs of cognitive relationships between N individuals A1A2...An: (A1A2)(A2A3)...(AnA1), and no other Recognize relationship. For example, the four-sided relationship means that AB, BC, CD, and DA of ABCD know each other, but AC and BD do not know each other. In the national competition, in order to prevent cheating, it is stipulated that any pair of people who know each other cannot be in a team, the king You know, at least how many detachments can be divided into.

Input

The first line contains two integers N and M. 1<=N<=10000, 1<=M<=1000000. Indicates that there are N people and M pairs of acquaintances. Enter a pair of friends in each of the next M lines

Output

Output an integer, the minimum number of teams that can be divided

Sample Input

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

Sample Output

3

HINT

One option (1,3)(2)(4)   
------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -----
    was slightly pitted by cena, the first time I made some violence, the largest group measured on cena was 0.89s, and after O(m+n) optimization, it was 1.5s+...
    Then I made a deal on bzoj, and the result is as follows:     it is much faster than the first time, it may be the problem of windows or cena, but I am not going to get into it. -------------------------------------------------- -------------------------------------------------- -----------------------------------------     After understanding the meaning of the question, I found that this is a The problem of minimum point coloring, but the ordinary method will definitely time out.     First of all, we need to understand the definition of a chord graph: when any ring with a length greater than 3 in the graph has at least one chord,  an undirected graph is called a chord. Figure .
    



    For this question, the absence of four-angle, five-angle, etc. relationships mentioned in the title indicates that the graph is a chord graph. We can do this with the special properties of chord diagrams, which, of course, involve a lot of definitions. ( Click to open the link if you read this article, you can jump directly to the next dividing line)
    A big wave of definitions is coming...
     Subgraph:  graph G = (V, E), then G' = (V' , E'), V' ⊆V, E' E is a subgraph of graph G.
     团: 图G的一个子图G' = (V', E' )  ,G' 为关于V', 的完全图。
     诱导子图:G = (V, E), G' = (V', E'), V' ⊆V, E' = {(u, v)|u,v∈V', (u, v) ∈E } 中, 图G'称为图G的诱导子图。
    单纯点:设N(v)表示与点v相邻的点集。一个点称为单纯点当{v} + N(v)的诱导子图为一个团。
    完美消除序列: 一个点的序列(每个点出现且恰好出现一次)v1, v2, …, vn满足vi在{vi, vi+1,…,vn}的诱导子图中为一个单纯点。
---------------------------------------------------------------------------------------------------------------------------------------------
    那么, 完美消除序列从后往前依次给每个点染色,给每个点染上可以染的最小的颜色。这时染的最大的颜色即为答案。
    求完美消除序列时, 用到了最大势算法(其实是因为LexBFS不会写QAQ), 这样一来, 整道题的框架就出来了。不过最大势算法的复杂度却是关键, 前面已经说过, 第一次提交时我用的是O(n²)  的暴力算法, 但显然有更优的, 用堆可以优化到O(nlogn), 但我更倾向于O(n+m)的链表求法。
    考虑从0到n的链表, 数字表示该链表中的点的当前势, 同时用一个数组flag和一个变量maxs记录点是否在序列中和当前最大势。 每次在最大势的链表上取出一个不再序列中的点, 若链表取完, 则maxs--, 直到取出一个点。 将该点加到序列中, 并将与之相连的不再序列中的点的势+1, 更新maxs并将之挂到相应的链表上, 这样就做到了O(n+m)的复杂度。
---------------------------------------------------------------------------------------------------------------------------------------------
CODE:
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
#define N 10000 + 10
#define M 2000000 + 10

using namespace std;

struct edge
{
    int to, next;
}e[M];
int n, m, num, ans, maxs;
int p[N], seq[N], col[N], lab[N], flag[N];
struct node
{
    int now;
    node *next;
}f[N];//链表
void add(int x, int y)
{
    e[++num].to = y;
    e[num].next = p[x];
    p[x] = num;
}
void put(int x)
{
    node *po = (struct node *)malloc(sizeof(struct node));
    po->next = f[lab[x]].next;
    po->now = x;
    f[lab[x]].next = po;
}//链表的插入
void read(int &x)
{
    x = 0;
    char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9')
    {
        x = (x << 1) + (x << 3) + c - '0';
        c = getchar();
    }
}
void init()
{
    int x, y;
    read(n), read(m);
    for (int i = 1; i <= m; ++i)
    {
        read(x), read(y);
        if (x == y) continue;
        add(x, y);
        add(y, x);
    }
}
void create()
{
    for (int i = 1; i <= n; ++i)
    f[i].next = NULL;//
    for (int i = 1; i <= n; ++i) put(i);
    maxs = 0;//初始化
    for (int i = n; i; i--)//用逆序求
    {
        node *po = f[maxs].next;//找到当前最大
        while(flag[po->now])
        {
            f[maxs].next = po = po->next;//及时删除没有用的点(漏掉的话会超时)
            while(po == NULL)
            {
                maxs--;
                po = f[maxs].next;
            }
        }
        f[maxs].next = po->next;//更新
        while(f[maxs].next == NULL) maxs--;
        int x = po->now;
        flag[x] = 1, seq[i] = x;
        for (int j = p[x]; j; j = e[j].next)
        if (!flag[e[j].to])
        {
            ++lab[e[j].to];//加势
            if (lab[e[j].to] > maxs) maxs = lab[e[j].to];
            put(e[j].to);
        }
    }
}
void paint()
{
    for (int i = 1; i <= n; ++i)
    flag[i] = -1;
    for (int i = n; i; i--)
    {
        int x = seq[i];
        for (int j = p[x]; j; j = e[j].next)
        flag[col[e[j].to]] = i;
        for (int j = 1; j <= n; ++j)
        if (flag[j] != i)
        {
            col[x] = j;
            break;
        }
        if (ans < col[x]) ans = col[x];
    }
}
void deal()
{
    create();
    paint();
    printf("%d\n", ans);
}
int main()
{
    freopen("kingdom.in", "r", stdin);
    freopen("kingdom.out", "w", stdout);
    init();
    deal();
    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326383532&siteId=291194637