您的位置:首页 > 其它

【tarjan求双连通分量+染色判二分图】POJ 2942

2012-03-15 02:08 351 查看
这题debug的好郁闷啊!!!先是染色有问题,然后就是各种小错误....

判奇圈可以用二分图标准,因为奇圈肯定不是二分图,之前还要分离各双连通分量.......染色法判二分图一定要先对分量里每一个点都染一次色再枚举任意两个相邻的点看是否有同色,就是因为这里wa了n次!!!

#define N 1005
vector<int> v
;
vector<int> lin
;
int dfn
,low
;
bool instack
,iscut
;
int num_rt;
int cnt;
int step;
stack<int> sta;
bool g

;
void init(int n){
for(int i=0;i<=n;i++){
instack[i] = 0;
iscut[i] = 0;
dfn[i] = 0;
low[i] = 0;
}
step = 0;
cnt = 0;
while(!sta.empty())sta.pop();
}
void tarjan(int u,int fa){
low[u] = dfn[u] = ++step;
sta.push(u);
instack[u] = 1;
int i;
for(i=0;i<v[u].size();i++){
int to = v[u][i];
if(to==fa)continue;
if(!dfn[to]){
tarjan(to,u);
low[u] = min(low[u],low[to]);
if(low[to]>=dfn[u]){
if(fa==-1)num_rt++;
else iscut[u] = 1;
while(1){
int tmp = sta.top();
sta.pop();
iscut[tmp] = 0;
instack[tmp] = 0;
lin[cnt].push_back(tmp);
if(tmp==to)break;
}
lin[cnt].push_back(u);
cnt++;
}
} else if(instack[to]) low[u] = min(low[u],dfn[to]);
}
}
int col
;
bool dfs(int id,int u,int c){
int i;
col[u] = c;
for(i=0;i<lin[id].size();i++){
int to = lin[id][i];
if(u==to || col[to]!=-1)continue;
if(g[u][to]){
dfs(id,to,c^1);
}
}
return true;
}
bool ok
;
int solve(int n){
int i,j;
for(i=1;i<=n;i++){
if(!dfn[i]){
num_rt = 0;
tarjan(i,-1);
if(num_rt>=2){
iscut[i] = 1;
}
}
}
int ans = 0;
memset(ok,false,sizeof(ok));
bool tag = 0;
for(i=0;i<cnt;i++){
for(j=0;j<=n;j++)col[j]=-1;
int sz = lin[i].size();
dfs(i,lin[i][0],1);
bool tag = 0;
for(j=0;j<sz;j++){
for(int k=0;k<sz;k++){
int a = lin[i][j],b = lin[i][k];
if(a!=b && g[a][b] && col[a]==col[b]){
tag = 1;
break;
}
}
if(tag)break;
}
if(tag){
for(j=0;j<sz;j++){
ok[lin[i][j]] = 1;
}
}
}
for(i=1;i<=n;i++){
if(!ok[i])ans++;
}
return ans;
}

int main(){
int n,m;
while(scanf("%d%d",&n,&m) &&(n+m)){
int i,j;
memset(g,true,sizeof(g));
init(n);
while(m--){
int x,y;
scanf("%d%d",&x,&y);
g[x][y] = g[y][x] = false;
}
for(i=0;i<=n;i++){
v[i].clear();
lin[i].clear();
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(g[i][j] && i!=j){
v[i].push_back(j);
}
}
}
printf("%d\n",solve(n));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐