首页 > 代码库 > bzoj 1006: [HNOI2008]神奇的国度 弦图的染色问题&&弦图的完美消除序列
bzoj 1006: [HNOI2008]神奇的国度 弦图的染色问题&&弦图的完美消除序列
1006: [HNOI2008]神奇的国度
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1788 Solved: 775
[Submit][Status]
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
1 2
1 4
2 4
2 3
3 4
Sample Output
3
HINT
一种方案(1,3)(2)(4)
Source
真是惊讶这种怪图还有那么一堆算法,传送门:http://wenku.baidu.com/link?url=dqd1T3C4o5DAjuPwQ_v44DnCHtQn5kxI-HoSsDb_QqSJQ0MeByzYYmpGSDSYXjPTsGQF9nz1AliKkp_-TvSxfTZQsDO3VHfeEd0yigbEgVC
这道题用到了弦图的完美消除序列,MCS最大势算法,虽然没有搞懂,但是这个算法背起来应该还是比较顺口,考场上只有yy了。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;#define MAXN 10010#define MAXE 2100000inline int nextInt(){ int x=0; char ch; while (ch=getchar(),ch<‘0‘||ch>‘9‘); do x=x*10+ch-‘0‘; while (ch=getchar(),ch<=‘9‘&&ch>=‘0‘); return x;}struct Edge{ int np; Edge *next;}E[MAXE],*V[MAXN];int tope=-1;inline void addedge(int x,int y){ E[++tope].np=y; E[tope].next=V[x]; V[x]=&E[tope];}int n,m;bool vis[MAXN];int cnt[MAXN];int seq[MAXN];int pos[MAXN];bool operator <(pair<int,int> p1,pair<int,int> p2){ return p1.second>p2.second;}struct cmp_c{ bool operator ()(pair<int,int> p1,pair<int,int> p2) { return p1.second<p2.second; }};priority_queue<pair<int,int>,vector<pair<int,int> >,cmp_c > Q;bool fl[10000];int col[MAXN];int main(){ freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); int i,j,k; int x,y,z; scanf("%d%d",&n,&m); for (i=0;i<m;i++) { x=nextInt(); y=nextInt(); addedge(x,y); addedge(y,x); } int now; int rk=n+1; Edge *ne; Q.push(make_pair(1,cnt[1])); while (!Q.empty()) { now=Q.top().first; Q.pop(); if (vis[now])continue; vis[now]=true; seq[--rk]=now; pos[now]=rk; for (ne=V[now];ne;ne=ne->next) { if (vis[ne->np])continue; cnt[ne->np]++; Q.push(make_pair(ne->np,cnt[ne->np])); } } Edge *ne2; int mx=0; int ans=0; for (i=n;i>=1;i--) { now=seq[i]; memset(fl,0,sizeof(fl[0])*(mx+1)); for (ne=V[now];ne;ne=ne->next) { if (pos[ne->np]<i)continue; fl[col[ne->np]]=true; mx=max(mx,col[ne->np]); } for (j=1;j<=mx+1;j++) { if (!fl[j]) { col[now]=j; ans=max(ans,j); break; } } } printf("%d\n",ans);}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。