Test instructions: http://www.lydsy.com/JudgeOnline/problem.php?id=1064
To dye a map, each point must follow the same, ask at least & how many kinds of staining scheme
Sol: The figure consists of a plurality of unicom blocks, for each unicom block, consider the following 3 kinds of situations:
If there is a ring, divided into 3 categories of discussion
For the first simple ring, the answer must be the approximate length of the ring
For the second ring with a reverse edge, the answer must be an approximate number of two chain lengths
Trick: will have a forward edge to the non-facing edge, the forward Benquan is 1, the reverse is-1
So you can do it together.
For the third kind of large ring set small ring, small ring contraction point can be (GCD (A, B) =gcd (b,a-b))
So the answer is maximum for all ring length gcd, the smallest of which is the smallest of the GCD >3
If it's a forest
The maximum answer is the maximum value of the difference in depth, and the minimum value is 3.
If the maximum value of <3 is not solved
#include <iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespacestd;Const intn=200010;Const intm=4000100;intN,m,tot,maxn,minn,ansmin,ansmax;intDis[n],head[n],vis[n],ver[m],nxt[m],edge[m];voidAddintUintVintd) {Tot++; Nxt[tot]=Head[u]; Ver[tot]=v; Edge[tot]=D; Head[u]=tot;}intgcdintXinty) { if(!y)returnx; returnGCD (y,x%y);}voidDFS1 (intXintFa//looking for a ring{vis[x]=1; for(intI=head[x];i;i=Nxt[i]) { intv=Ver[i]; if(v!=FA) { if(!vis[v]) vis[v]=1, dis[v]=dis[x]+EDGE[I],DFS1 (v,x); ElseANSMAX=GCD (Ansmax,abs (dis[x]-dis[v]+edge[i])); } }}voidDFS2 (intXintFa//handling forests{vis[x]=1; MAXN=Max (DIS[X],MAXN); Minn=min (minn,dis[x]); for(intI=head[x];i;i=Nxt[i]) { intv=Ver[i]; if(v!=FA)if(!Vis[v]) Vis[v]=1, dis[v]=dis[x]+EDGE[I],DFS2 (v,x); }}intMain () {scanf ("%d%d",&n,&m); while(m--) { intb; scanf"%d%d",&a,&b); Add (A, B,1); Add (b,a,-1); } for(intI=1; i<=n;i++)if(!vis[i]) DFS1 (i,0); if(Ansmax) for(ansmin=3; ansmin<=ansmax&&ansmax%ansmin;ansmin++); Else{ansmin=3; memset (Vis,0,sizeof(VIS)); for(intI=1; i<=n;i++) if(!Vis[i]) {MAXN=minn=0, dis[i]=0; DFS2 (i,0); ansmax+=maxn-minn+1; } } if(ansmax<=2) ansmax=ansmin=-1; printf ("%d%d\n", ansmax,ansmin); return 0;}
Bzoj 1064 "noi2008" masked Ball