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; }