[BZOJ1006]神奇的国度(完美消除序列)
2017-09-15 20:15
351 查看
前言
题面见链接http://www.lydsy.com/JudgeOnline/problem.php?id=1006
前置技能
完美消除序列
资料链接:https://wenku.baidu.com/view/6f9f2223dd36a32d73758126.html
具体算法在文档的第18-46页
解析
首先我们分析题面
所以我们容易得出结论:这个图是一个弦图,可以直接在其上跑一个完美消除序列
然后我们就可以对这个序列依次染色,在文档第60-69页
此处使用的是最大势算法,因为采用了链表优化所以复杂度为O(n+m)
注意:网上部分题解复杂度为O(n*(n+m))或O(mlogn)
这里补一个复杂度为O(mlogn) 的最大势
题面见链接http://www.lydsy.com/JudgeOnline/problem.php?id=1006
前置技能
完美消除序列
资料链接:https://wenku.baidu.com/view/6f9f2223dd36a32d73758126.html
具体算法在文档的第18-46页
解析
首先我们分析题面
为了巩固三角关系,K国禁止四边关系,五边关系等等的存在
所以我们容易得出结论:这个图是一个弦图,可以直接在其上跑一个完美消除序列
然后我们就可以对这个序列依次染色,在文档第60-69页
此处使用的是最大势算法,因为采用了链表优化所以复杂度为O(n+m)
注意:网上部分题解复杂度为O(n*(n+m))或O(mlogn)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<ctime> #include<cmath> #include<algorithm> #include<cctype> #include<iomanip> #include<vector> #include<list> #define int long long using namespace std; inline int read(){ int i=0,f=1; char ch; for(ch=getchar();!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) i=(i<<3)+(i<<1)+(ch^48); return i*f; } int buf[1024]; inline void write(int x){ if(!x){putchar('0');return ;} if(x<0){putchar('-');x=-x;} while(x){buf[++buf[0]]=x%10,x/=10;} while(buf[0]) putchar(buf[buf[0]--]+48); return ; } #define stan 11111 #define sten 2222222 struct M_S_C{ int l,r; }tlist[stan<<1]; int tot,nxt[sten],first[stan],goal[sten],reco[stan],co[stan],maxc,n,m,a,b,ans; int sa[stan],sze[stan],tag[stan]; inline void addedge(int a,int b){ nxt[++tot]=first[a];first[a]=tot;goal[tot]=b; nxt[++tot]=first;first[b]=tot;goal[tot]=a; return ; } inline void add(int val,int num){ num+=10000; tlist[num].r=tlist[val].r; tlist[num].l=val; tlist[tlist[val].r].l=num; tlist[val].r=num; } inline void del(int num){ num+=10000; tlist[tlist[num].r].l=tlist[num].l; tlist[tlist[num].l].r=tlist[num].r; return ; } inline void msc(){ for(int i=1;i<=n;++i) add(0,i); maxc=0; for(int i=1;i<=n;++i){ while(tlist[maxc+1].r!=maxc+1) ++maxc; while(maxc&&tlist[maxc].r==maxc) --maxc; int u=tlist[maxc].r-10000; sa[i]=u;tag[u]=true; del(u); for(int p=first[u];p;p=nxt[p]) if(!tag[goal[p]]){ ++sze[goal[p]]; del(goal[p]); add(sze[goal[p]],goal[p]); } } } inline void color(int u){ for(int p=first[u];p;p=nxt[p]) if(co[goal[p]]) reco[co[goal[p]]]=u; for(int i=1;i<=n;++i) if(reco[i]!=u){ co[u]=i; break; } return ; } inline void getmaxcolor(){ for(int i=1;i<=n;++i) color(sa[i]); for(int i=1;i<=n;++i) ans=max(ans,co[i]); return ; } signed main(){ n=read();m=read(); for(int i=1;i<=n;++i) tlist[i].l=tlist[i].r=i; for(int i=1;i<=m;++i){ a=read();b=read(); addedge(a,b); } msc(); getmaxcolor(); write(ans); return 0; }[b]附录
这里补一个复杂度为O(mlogn) 的最大势
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<ctime> #include<cmath> #include<algorithm> #include<cctype> #include<iomanip> #include <vector> #include <queue> #define int long long using namespace std; inline int read(){ int i=0,f=1; char ch; for(ch=getchar();!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) i=(i<<3)+(i<<1)+(ch^48); return i*f; } int buf[1024]; void write(int x){ if(!x){putchar('0');return ;} if(x<0){putchar('-');x=-x;} while(x){buf[++buf[0]]=x%10,x/=10;} while(buf[0]) putchar(buf[buf[0]--]+48); return ; } #define stan 11111 vector <int> arc[stan]; priority_queue <pair<int,int> > que; int m,ans,n,b,a,label[stan],r[stan],tag[stan],sa[stan]; void color(int x){ for(int i=0;i<arc[x].size();++i) if(label[arc[x][i]]!=-1) r[label[arc[x][i]]]=x; for(int i=1;label[x]==-1;++i) if(r[i]!=x) label[x]=i; return ; } void cdqcga(){ memset(tag,-1,sizeof(tag)); for(int i=1;i<=n;++i) //MCS O(mlogn) que.push(make_pair(0,i)); for(int cnt=n;cnt;){ int tmp=que.top().second; que.pop(); if(tag[tmp]!=-1) continue; sa[cnt]=tmp;tag[tmp]=cnt--; for(int i=0;i<arc[tmp].size();++i){ int u=arc[tmp][i]; if(tag[u]!=-1) continue; ++label[u]; que.push(make_pair(label[u], u)); } } memset(label,-1,sizeof(label)); memset(r,-1,sizeof(r)); for(int i=n;i;--i) color(sa[i]); for(int i=1;i<=n;++i) ans=max(ans,label[i]); return ; } signed main(){ n=read();m=read(); for(int i=1;i<=m;++i){ a=read();b=read(); arc[a].push_back(b); arc[b].push_back(a); } cdqcga(); write(ans); return 0; }
相关文章推荐
- [BZOJ1006][[HNOI2008]神奇的国度][MCS,完美消除序列]
- bzoj 1006: [HNOI2008]神奇的国度 弦图的染色问题&&弦图的完美消除序列
- [完美消除序列]BZOJ1006: [HNOI2008]神奇的国度
- BZOJ 1006 神奇的国度[弦图 MCS求完美消除序列]
- [弦图 最小染色 完美消除序列 MCS算法] BZOJ 1006 [HNOI2008]神奇的国度
- bzoj1006 神奇的国度【完美消除序列】
- 弦图与完美消除序列(bzoj 1006: [HNOI2008]神奇的国度)
- bzoj1006 弦图转完美消除序列,最小染色
- BZOJ 1006 最大势算法(完美消除序列求最小染色)
- BZOJ 1006 神奇的国度(弦图的染色数)
- [BZOJ1006][HNOI2008][弦图的最小点染色]神奇的国度
- [BZOJ 1006] [HNOI2008] 神奇的国度 【弦图最小染色】
- BZOJ 1006: [HNOI2008]神奇的国度(最大势算法-弦图染色)
- bzoj 1006: [HNOI2008]神奇的国度 弦图最小染色 最大势算法
- BZOJ-1006 神奇的国度
- BZOJ 1006 神奇的国度
- BZOJ 1006: [HNOI2008]神奇的国度(弦图染色)
- bzoj1006 [HNOI2008]神奇的国度
- 【BZOJ】1006: [HNOI2008]神奇的国度
- [BZOJ1006]神奇的国度