【图论】[POJ 2942]Knights of the Round Table
先找连通图,然后检查是否是二分图注意如果是在线的算法记得要清空Color数组因为存在一种情况儿子中含有两个连通图,那么自己儿子中就会存在一个割点已经被染了色,就有可能存在冲突。
#include <cstdio>
#include <algorithm>
#include <stack>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int MAXN = 1000;
const int MAXM = 1000000;
vector<int> vec;
struct node {
int v;
node *next;
}Edges[MAXM*2+10], *adj[MAXN+10], *ecnt=Edges;
void addedge(int u, int v){
++ecnt;
ecnt->v = v;
ecnt->next = adj[u];
adj[u] = ecnt;
}
int dfn[MAXN+10], low[MAXN+10], dcnt;
int kcnt, Color[MAXN+10], from[MAXN+10];
bool vis[MAXN+10]; bool Mp[MAXN+2][MAXN+2];
bool check(int u, int id, int c){
Color[u]=c;
for(node *p=adj[u];p;p=p->next) if(from[p->v] == id){
if(Color[p->v] && Color[p->v] == Color[u])
return false;
if(!Color[p->v] && !check(p->v, id, 3-c))
return false;
}
return true;
}
stack<int> sta;
void dfs(int u, int fa){
dfn[u] = low[u] = ++dcnt; sta.push(u);
for(node *p=adj[u];p;p=p->next){
int v = p->v;
if(!dfn[v]){
dfs(v, u);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u]){
++kcnt;
vec.clear();
int tmp;
do{
vec.push_back( sta.top() );
from[(tmp=sta.top())] = kcnt;
sta.pop(); Color[tmp] = 0;
}while(tmp != v);
vec.push_back(u);
int Len = vec.size();
if(!check(u, kcnt, 1) && Len >= 3){
for(int j=0;j<Len;j++)
vis[vec[j]] = true;
}
}
}else if(v!=fa)
low[u] = min(low[u], dfn[v]);
}
}
int first;
bool solve(){
int n, m, u, v;
scanf("%d%d", &n, &m);
if(!n && !m) return false;
ecnt = Edges;
memset(adj, 0, sizeof adj);
memset(dfn, 0, sizeof dfn);
memset(low, 0, sizeof low);
memset(vis, 0, sizeof vis);
memset(Color, 0, sizeof Color);
memset(Mp, 0, sizeof Mp);
memset(from, 0, sizeof from);
dcnt = 0; kcnt = 0;
while(!sta.empty()) sta.pop();
for(int i=0;i<m;i++){
scanf("%d%d", &u, &v);
Mp[u][v] = Mp[v][u] = true;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(!Mp[i][j]){
addedge(i, j);
addedge(j, i);
}
int ans = n;
for(int i=1;i<=n;i++)
if(!dfn[i])
dfs(i, -1);
for(int i=1;i<=n;i++)
if(vis[i])
ans--;
printf("%d\n", ans);
return true;
}
int main(){
while(solve());
return 0;
}