书上学习二分图的一个例题。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
const int maxe=1010;
const int maxv=10e5+10;
struct Edge
{
int u;
int v;
};
int n,m,odd[maxv],color[maxv];
int a[maxe][maxe],pre[maxe],bccno[maxe],dfs_clock,bcc_cnt;
bool iscut[maxe];
vector<int> g[maxe],bcc[maxe];
stack<Edge> s;
int dfs(int u,int fa)
{
int lowu=pre[u]=++dfs_clock;
int child=0;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
Edge e=(Edge){u,v};
if(!pre[v])
{
s.push(e);
child++;
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>=pre[u])
{
iscut[u]=1;
bcc_cnt++;
bcc[bcc_cnt].clear();
for(;;)
{
Edge x=s.top();
s.pop();
if(bccno[x.u]!=bcc_cnt)
{
bcc[bcc_cnt].push_back(x.u);
bccno[x.u]=bcc_cnt;
}
if(bccno[x.v]!=bcc_cnt)
{
bcc[bcc_cnt].push_back(x.v);
bccno[x.v]=bcc_cnt;
}
if(x.u==u&&x.v==v)
break;
}
}
}
else if(pre[v]<pre[u]&&v!=fa)
{
s.push(e);
lowu=min(lowu,pre[v]);
}
}
if(fa<0&&child==1)
iscut[u]=0;
return lowu;
}
void find_bcc(int n)
{
memset(pre,0,sizeof(pre));
memset(iscut,0,sizeof(iscut));
memset(bccno,0,sizeof(bccno));
dfs_clock=bcc_cnt=0;
for(int i=0;i<n;i++)
if(!pre[i])
dfs(i,-1);
}
bool bipartite(int u,int b)
{
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(bccno[v]!=b)
continue;
if(color[v]==color[u])
return false;
if(!color[v])
{
color[v]=3-color[u];
if(!bipartite(v,b))
return false;
}
}
return true;
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n||m))
{
for(int i=0;i<n;i++)
g[i].clear();
memset(a,0,sizeof(a));
for(int i=0;i<m;i++)
{
int ita,itb;
scanf("%d%d",&ita,&itb);
ita--;itb--;
a[ita][itb]=a[itb][ita]=1;
}
for(int u=0;u<n;u++)
for(int v=u+1;v<n;v++)
if(!a[u][v])
{
g[u].push_back(v);
g[v].push_back(u);
}
find_bcc(n);
memset(odd,0,sizeof(odd));
for(int i=1;i<=bcc_cnt;i++)
{
memset(color,0,sizeof(color));
for(int j=0;j<bcc[i].size();j++)
bccno[bcc[i][j]]=i;
int u=bcc[i][0];
color[u]=1;
if(!bipartite(u,i))
for(int j=0;j<bcc[i].size();j++)
odd[bcc[i][j]]=1;
}
int ans=n;
for(int i=0;i<n;i++)
if(odd[i])
ans--;
printf("%d\n",ans);
}
return 0;
}