BZOJ 1006: [HNOI2008]神奇的国度 弦圖
題目:
給出一個圖,圖中所有的環的長度不大於3,現在需要分組,使得每個組不在同一個環內。
分析:
求弦圖的染色數目。
具體請看這篇文章:弦图与区间图 陈丹琦
MCS算法:
col[i]表示點i與col[i]個已經遍歷過的點存在邊,即它不能用的顏色數。
找所有沒有遍歷過的點當中最大的col值的點。
從一個點出發,相鄰並且沒有遍歷過的 col[y] ++。
重複n次,max(col[i]+1)就是答案
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; #define debug puts("here") #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define REP(i,a,b) for(int i=a;i<=b;i++) #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++) #define pb push_back #define RD(n) scanf("%d",&n) #define RD2(x,y) scanf("%d%d",&x,&y) #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w) /******** program ********************/ const int MAXN = 10005; const int MAXM = 2000005; int po[MAXN],tol; int col[MAXN]; int lab[MAXN]; struct node{ int y,next; }edge[MAXM]; void add(int x,int y){ edge[++tol].y = y; edge[tol].next = po[x]; po[x] = tol; } int main(){ #ifndef ONLINE_JUDGE freopen("sum.in","r",stdin); //freopen("sum.out","w",stdout); #endif int x,y,n,m; RD2(n,m); while(m--){ RD2(x,y); add(x,y); add(y,x); } int ans = 0; for(int q=n;q;q--){ int k = 0; rep1(i,n) // 找沒被遍歷過的最大col值的點 if(!lab[i]&&col[i]>=col[k]) k = i; lab[k] = q; // 標記為q // 從相鄰點出發,沒被遍歷過的點的col值加一 for(int i=po[k];i;i=edge[i].next) if(!lab[ edge[i].y ]) ans = max(ans,++col[ edge[i].y ] ); // 順便更新答案 } cout<<ans+1<<endl; return 0; }