[HNOI2008]神奇的国度

题目描述

K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.

所谓N边关系,是指N个人 A1A2…An之间仅存在N对认识关系:(A1A2)(A2A3)…(AnA1),而没有其它认识关系.比如四边关系指ABCD四个人 AB,BC,CD,DA相互认识,而AC,BD不认识.全民比赛时,为了防止做弊,规定任意一对相互认识的人不得在一队,国王相知道,最少可以分多少支队。

输入格式

第一行两个整数N,M。1<=N<=10000,1<=M<=1000000.表示有N个人,M对认识关系. 接下来M行每行输入一对朋友

输出格式

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

输入输出样例

输入 #1 复制

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

输出 #1 复制

3

题解

一句话题意:求弦图的最小染色数(不求方案)

在完美图中,最小染色数等于团数,弦图是完美图,所以直接跑一遍最大势算法,最终答案就是 M a x i = 1 n { l a b e l [ i ] + 1 } Max_{i=1}^{n}\{label[i]+1\} Maxi=1n{label[i]+1}

直接放代码:

#include
using namespace std;
namespace fastio{
	template<typename tn> void read(tn &a){
	    tn x=0,f=1;char c=' ';
	    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	    for(;isdigit(c);c=getchar() ) x=x*10+c-'0';
	    a=x*f;
	}
	template<typename tn> void print(tn a){
	    if(a<0) putchar('-'),a=-a;
	    if(a>9) print(a/10);
	    putchar(a%10+'0');
	}
};
using namespace fastio;
const int N=1e4+5;
const int M=1e6+5;
struct Edge{
	int nex,to;
}e[M*2];
int head[N],cnt=1,label[N],xu[N],num;
int max_x,max_d;
bool vis[N];
void add(int x,int y){
	e[++cnt].nex=head[x];
	head[x]=cnt;
	e[cnt].to=y;
}
int n,m;
vector<int> v[N];
int main(){
	read(n);
	read(m);
	for(int i=1;i<=m;i++){
		int x,y;
		read(x);
		read(y);
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;i++) v[0].push_back(i);
	int best=0;
	for(int i=1,now=0;i<=n;i++){
		bool flag=0;
		while(!flag){
			for(int j=v[best].size()-1;j>=0;j--){
				if(vis[v[best][j]]) v[best].pop_back();
				else {flag=1;now=v[best][j];break;} 
			} 
			if(!flag) best--;
		}
		xu[++num]=now;vis[now]=1;
		for(int i=head[now];i;i=e[i].nex){
			int y=e[i].to;
			if(!vis[y]){
				v[++label[y]].push_back(y);
				best=max(best,label[y]);
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++)  ans=max(ans,label[i]+1);
	printf("%d\n",ans);
	return 0;
}

你可能感兴趣的:(题解,图论)