Analysis
因为有环,所以可以先tarjan算法求出e-DCC(边双连通分量),这个时候就要去染色, 这时候我们就要思考对于每一个分量我们需要多少种颜色,其实不难看出,如果存在奇环 (就像1->2->3->4->1,我们发现如果仅用两种颜色,是没办法使每条边两端的端点的颜 色不同),于是对于每一个连通分量跑一次dfs,如果存在奇环,说明要用三种颜色才能满足。
代码实现
#include
using namespace std;
const int N=1e4+10;
int n,cnt,tot,scc,ans=2,m;
int h[N],nex[N],dfn[N],eg[N],low[N],id[N],col[N],ver[N];
inline void add(int x,int y)
{
nex[tot]=h[x];
ver[tot]=y;
h[x]=tot++;
}
inline void tarjan(int u,int deg)
{
dfn[u]=low[u]=++cnt;
for (int i=h[u];~i;i=nex[i])
{
int j=ver[i];
if(!dfn[j])
{
tarjan(j,i);
low[u]=min(low[u],low[j]);
if(dfn[u]<low[j])
eg[i]=eg[i^1]=1;
}
else if(i!=(deg^1)) low[u]=min(low[u],dfn[j]);
}
}
inline void dfs(int u)
{
for (int i=h[u];~i;i=nex[i])
{
int j=ver[i];
if(!col[j])
{
col[j]=3-col[u];
dfs(j);
}
else if(col[j]==col[u]) ans=3;
}
}
int main()
{
memset(h,-1,sizeof(h));
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
for (int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i,0);
for (int i=1;i<=n;i++)
if(!col[i]) col[i]=1,dfs(i);
printf("%d\n",ans);
return 0;
}后话
我相信这只是其中一种解法,但是对我来说比较好理解,如果有不足之处也请各位多多包涵

京公网安备 11010502036488号