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

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

 

题解:

所有人的关系图是一张弦图,即长度超过3的环中必有一条弦。

求它的完美性消除序列,根据完美性消除序列逆序贪心的染色,最终所用的色数就是答案。

真的很难,俺蒙蔽了。

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=10010;
vector<int> g[maxn];
int N,M;
int r[maxn];
int sa[maxn];
int label[maxn];
priority_queue<pair<int,int> > q;
void construct () {
    fill(r+1,r+N+1,-1);
    fill(label+1,label+N+1,0);
    for (int i=1;i<=N;i++) 
        q.push(make_pair(0,i));
    for (int i=N;i>=1;) {
        int id=q.top().second;
        q.pop();
        if (r[id]!=-1) continue;
        sa[i]=id;
        r[id]=i--;
        for (int j=0,len=g[id].size();j<len;j++) {
            int u=g[id][j];
            if (r[u]!=-1) continue;
            label[u]++;
            q.push(make_pair(label[u],u));
        }
    }
}

void color (int u) {
    for (int i=0,len=g[u].size();i<len;i++) {
        int v=g[u][i];
        if (label[v]==-1) continue;
        r[label[v]]=u;
    }
    for (int i=1;label[u]==-1;i++)
        if (r[i]!=u) label[u]=i;
}

int color_Graph () {
    fill(label,label+N+1,-1);
    fill(r+1,r+1+N,-1);
    for (int i=N;i>0;i--) 
        color(sa[i]);
    int ans=0;
    for (int i=1;i<=N;i++)
        ans=max(ans,label[i]);
    return ans;
}

int main () {
    scanf("%d%d",&N,&M);
    for (int i=1;i<=N;i++) 
        g[i].clear();
    for (int i=0;i<M;i++) {
        int x,y;
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    construct();
    printf("%d\n",color_Graph());
    return 0;
}

 

posted @ 2020-03-14 21:12  zlc0405  阅读(127)  评论(0编辑  收藏  举报