[关键字]:2-sat
[题目大意]:http://poj.org/problem?id=3648
//=====================================================================================================
[分析]:http://blog.csdn.net/l04205613/article/details/6673512这个博客对于2-sat的题目总结的不错。
[代码]:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
using namespace std;
int n,m,sum,top;
int c[5100],s[5100],colour[5100];
bool v[5100];
vector<int> e[5100],re[5100],dag[5100];
int pre()
{
for (int i=0;i<5010;i++) {e[i].clear();re[i].clear();dag[i].clear();}
return 0;
}
int cal(int x,char ch)
{
int res=x*2;
if (ch=='h') return res; else return res+1;
}
int dfs1(int u)
{
v[u]=1;
int size=e[u].size();
for (int i=0;i<size;i++)
{
int temp=e[u][i];
if (!v[temp]) dfs1(temp);
}
s[++top]=u;
return 0;
}
int dfs2(int u)
{
v[u]=1;
int size=re[u].size();
for (int i=0;i<size;i++)
{
int temp=re[u][i];
if (!v[temp]) dfs2(temp);
}
c[u]=sum;
return 0;
}
int kosaraju()
{
sum=top=0;
memset(v,0,sizeof(v));
for (int i=0;i<2*n;i++)
if (!v[i]) dfs1(i);
memset(v,0,sizeof(v));
for (int i=2*n;i;i--)
if (!v[s[i]]) sum++,dfs2(s[i]);
for (int i=0;i<2*n;i++)
{
int size=re[i].size();
for (int j=0;j<size;j++)
{
int temp=re[i][j];
if (c[i]!=c[temp]) dag[c[i]].push_back(c[temp]);
}
}
return 0;
}
bool solveable()
{
for (int i=0;i<2*n;i+=2)
if (c[i]==c[i+1]) return 0;
return 1;
}
int dfs(int u)
{
colour[u]=2;
int size=dag[u].size();
for (int i=0;i<size;i++)
{
int temp=dag[u][i];
if (!colour[temp]) dfs(temp);
}
return 0;
}
int solve()
{
memset(colour,0,sizeof(colour));
for (int i=sum;i;i--)
{
if (!colour[i])
{
colour[i]=1;
for (int j=0;j<2*n;j++)
if (c[j]==i)
{
int temp=c[j^1];
if (!colour[temp]) dfs(temp);
}
}
}
for (int i=2;i<2*n;i++)
if (colour[c[i]]==colour[c[1]]) printf("%d%c ",i/2,i&1?'w':'h');
printf("\n");
return 0;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
getchar();
if (!n && !m) break;
int a,b,u,v;
char ch1,ch2;
pre();
for (int i=0;i<m;i++)
{
scanf("%d%c%d%c",&a,&ch1,&b,&ch2);
getchar();
u=cal(a,ch1),v=cal(b,ch2);
e[u].push_back(v^1),e[v].push_back(u^1);
re[v^1].push_back(u),re[u^1].push_back(v);
}
e[1].push_back(0),re[0].push_back(1);
kosaraju();
if (solveable()) solve(); else printf("bad luck\n");
}
return 0;
}