【最小染色】【HNOI 2008】【bzoj 1006】神奇的国度

1006: [HNOI2008]神奇的国度

Time Limit: 20 Sec  Memory Limit: 162 MB
Submit: 2446  Solved: 1101

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)

题解:

论文题。详见——>CDQ弦图与区间图

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 10010
#define M 1000100

struct Edge{
    int v,next;
}edge[M<<1];
int n,m,s,num=0,head[N],b[N],c[N],d[N],q[M];
bool vis[N]={0};

int in(){
    int x=0; char ch=getchar();
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    return x;
}

void add(int u,int v){
    edge[++num].v=v; edge[num].next=head[u]; head[u]=num;
}

int main(){
    n=in(),m=in(); s=0;
    for (int i=1; i<=m; i++){
        int u=in(),v=in();
        add(u,v),add(v,u);
    }

    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
    for (int i=n; i; i--){
        int k=0;
        for (int j=1; j<=n; j++)
            if (!vis[j] && d[j]>=d[k]) k=j;
        vis[k]=true; q[i]=k;
        for (int j=head[k]; j; j=edge[j].next)
            d[edge[j].v]++;
    }
    for (int i=n; i>0; i--){
        int k=q[i];
        for (int j=head[k]; j; j=edge[j].next)
            b[c[edge[j].v]]=i;
        for (int j=1; ; j++)
            if (b[j]!=i){
                c[k]=j;
                s=max(s,j);
                break;
            }
    }

    printf("%d\n",s);
    return 0;
}

你可能感兴趣的:(【最小染色】【HNOI 2008】【bzoj 1006】神奇的国度)