题目大意:
一个弦图,求最小点染色
思路:
使用最大势算法
完美消除序列从后往前依次给每个点,给每个点染上可以染的最小的颜色 ——cdq
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdlib> 6 #include<cstring> 7 #include<queue> 8 #include<map> 9 #include<vector> 10 #define ll long long 11 #define inf 2147483611 12 #define MAXN 10010 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int nxt[MAXN*200],fst[MAXN],to[MAXN*200],cnt,n,m,dis[MAXN]; 22 int q[MAXN],tmp,clr[MAXN],ans; 23 bool vis[MAXN]; 24 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 25 int main() 26 { 27 n=read(),m=read(); 28 int a,b; 29 for(int i=1;i<=m;i++) {a=read(),b=read();add(a,b);add(b,a);} 30 for(int i=n;i;i--) 31 { 32 tmp=0; 33 for(int j=1;j<=n;j++) 34 if(!vis[j]&&dis[j]>=dis[tmp]) tmp=j; 35 vis[tmp]=1,q[i]=tmp; 36 for(int j=fst[tmp];j;j=nxt[j]) dis[to[j]]++; 37 } 38 for(int i=n;i;i--) 39 { 40 memset(vis,0,sizeof(vis)); 41 for(int j=fst[q[i]];j;j=nxt[j]) vis[clr[to[j]]]=1; 42 for(int j=1;j<=n;j++) if(!vis[j]) {clr[q[i]]=j,ans=max(j,ans);break;} 43 } 44 printf("%d",ans); 45 }