题目描述
输入输出格式
输入格式:
输出格式:
输入输出样例
输入样例#1:
10 6
3h 7h
5w 3w
7h 6w
8w 3w
7h 3w
2w 5h
0 0
输出样例#1:
1h 2h 3w 4h 5h 6h 7h 8h 9h
分析
- 同性之间有通奸关系。由于他们不能和他们的伴侣在一边,所以我们只能让他们分别和对方的伴侣坐在一边。
- 异性之间有通奸关系。与第一点相同。
- 新娘和新郎之间连边。
一对伴侣之间不连边不会在一边。
\(ps:\)这题改了我一个晚上,急了,直接对着标程改了。。。。。。代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define il inline
#define re register
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x){
T f=1;x=0;char c;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=x*10+(c^48);
x*=f;
}
struct edge{
int to[131],nxt[131],head[61],cnt;
void addedge(int x,int y){
to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
}
}g1,g2;
int n,m;
int tot,tp,_index;
int vis[61];
int low[61],dfn[61],scc[61],stk[61],ano[61],tags[61],du[61];
void tarjan(int u){
vis[u]=1;low[u]=dfn[u]=++_index;stk[++tp]=u;
for(int i=g1.head[u];i;i=g1.nxt[i]){
int v=g1.to[i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
++tot;
while(stk[tp]!=u){
scc[stk[tp]]=tot;
vis[stk[tp]]=0;
--tp;
}
scc[stk[tp]]=tot,vis[stk[tp]]=0,--tp;
}
}
void topsort(){
tp=0;
for(int i=1;i<=tot;++i)
if(!du[i])
stk[++tp]=i;
while(tp){
int u=stk[tp];--tp;
if(!tags[u])
tags[u]=1,tags[ano[u]]=-1;
for(int i=g2.head[u];i;i=g2.nxt[i]){
int v=g2.to[i];
--du[v];
if(!du[v])
stk[++tp]=v;
}
}
}
void Two_SAT(){
for(int i=1;i<=n*2;++i)
if(!dfn[i])
tarjan(i);//2-SAT常规操作
for(int i=1;i<=n;++i){
if(scc[i]==scc[i+n]){
puts("bad luck");
return;
}
ano[scc[i]]=scc[i+n],ano[scc[i+n]]=scc[i];
}
for(int i=1;i<=n*2;++i){//缩点建新图
for(int j=g1.head[i];j;j=g1.nxt[j]){
int u=i,v=g1.to[j];
if(scc[v]!=scc[u]){
g2.addedge(scc[v],scc[u]);
++du[scc[u]];
}
}
}
topsort();//拓扑排序
for(int i=1;i<n;++i)
if(tags[scc[i]]==-1) printf("%dh ",i);
else printf("%dw ",i);
}
int main(){
fastio,tie0;
int c1,c2;
char opt1,opt2;
while(cin>>n>>m&&n&&m){
g1.cnt=g2.cnt=tp=tot=_index=0;
for(int i=1;i<=n*2;++i) g1.head[i]=g2.head[i]=dfn[i]=vis[i]=du[i]=tags[i]=0;//一堆初始化
for(int i=1;i<=m;++i){//连边
cin>>c1>>opt1>>c2>>opt2;
if(c1==0) c1=n;if(c2==0) c2=n;
if(opt1=='h'&&opt2=='h') g1.addedge(c1,c2+n),g1.addedge(c2,c1+n);
else if(opt1=='h'&&opt2=='w') g1.addedge(c1,c2),g1.addedge(c2+n,c1+n);
else if(opt1=='w'&&opt2=='h') g1.addedge(c1+n,c2+n),g1.addedge(c2,c1);
else g1.addedge(c1+n,c2),g1.addedge(c2+n,c1);
}
g1.addedge(n*2,n);//新娘和新郎
Two_SAT();
}
return 0;
}