版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/83549901
找割点,然后把栈中割点下的边拿出来塞在vector中,STL大法好。
POJ 2942 Knights of the Round Table
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<queue>
#include<stack>
#include<vector>
#define maxn 1005
using namespace std;
int n,m;
int dis[maxn][maxn],col[maxn];
struct Edge
{
int u,v,Prev;
Edge (int u=0,int v=0):u(u),v(v){}
}E[maxn*maxn];
int info[maxn],cnt_e;
inline void Node(int u,int v){ E[++cnt_e].Prev=info[u],info[u]=cnt_e,E[cnt_e].v=v,E[cnt_e].u=u; }
stack<Edge>s;
bool odd[maxn];
int dfn[maxn],low[maxn],tot,bct,vis[maxn];
vector<int>bcc[maxn];
void dfs(int now,int ff)
{
low[now] = dfn[now] = ++tot;
for(int i=info[now];i;i=E[i].Prev)
{
if(!dfn[E[i].v])
{
s.push(E[i]);
dfs(E[i].v,now);
low[now]= min(low[now] , low[E[i].v]);
if(low[E[i].v] >= dfn[now])
{
bcc[++bct].clear();
for(;!s.empty();)
{
if(vis[s.top().u]!=bct) vis[s.top().u]=bct,bcc[bct].push_back(s.top().u);
if(vis[s.top().v]!=bct) vis[s.top().v]=bct,bcc[bct].push_back(s.top().v);
if(s.top().u == now && s.top().v == E[i].v){s.pop(); break;}
s.pop();
}
}
}
else if(dfn[now] > dfn[E[i].v] && E[i].v!=ff)
s.push(E[i]), low[now] = min(low[now] , dfn[E[i].v]);
}
}
int tim = 0;
bool check(int now,int cl)
{
if(vis[now]!=tim) return 1;
if(col[now] && col[now]!=cl) return 0;
else if(col[now] && col[now] == cl) return 1;
else col[now] = cl;
for(int i=info[now];i;i=E[i].Prev)
if(!check(E[i].v,3-cl)) return 0;
return 1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(!n && !m) return 0;
memset(dis,0,sizeof dis);
memset(info,0,sizeof info);
memset(odd,0,sizeof odd);
memset(vis,0,sizeof vis);
memset(dfn,0,sizeof dfn);
for(;!s.empty();s.pop());
cnt_e=bct=tot=0;
for(int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),dis[u][v] = 1,dis[v][u] = 1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j && dis[i][j] == 0)
Node(i,j);
for(int i=1;i<=n;i++)
if(!dfn[i]) dfs(i,0);
for(int i=1;i<=bct;i++)
{
int siz = bcc[i].size();tim = i;
for(int j=0;j<siz;j++) vis[bcc[i][j]] = i,col[bcc[i][j]]=0;
if(!check(bcc[i][0],1))
for(int j=0;j<siz;j++) odd[bcc[i][j]] = 1;
}
int ans = 0;
for(int i=1;i<=n;i++)
ans += odd[i];
printf("%d\n",n-ans);
}
}