题意怪怪的,还不给输入规模_(:3 」∠)_,听说数据也是水的。难怪没有把边反向也可以过。。
n对夫妇,从0开始编号,其中0号为新郎和新娘,分别坐在两端。给出m对关系(i,j),i和j不能一起坐在新娘对面,这n对夫妇中任意一对不能坐在同一端。输出与新娘在同一端的其他n-1个人。
建图:
首先将0(新娘)和新郎(1)连一条边,表示新娘和新郎必须坐在不同端。
然后对于关系(i,j),连接 2i->2j+1,2j->2i+1,表示i和j的配偶必然坐于同一端,j和i的配偶也必然坐于同一端。
然后SCC缩点,若有解,则反向建边后进行拓扑排序求出方案。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
#define maxn 2005
#define maxm 1000005
vector<int> G[maxn];
int pre[maxn],low[maxn],sccno[maxn],dfs_clock,scc_cnt;
stack<int> S;
void dfs(int u){
pre[u]=low[u]=++dfs_clock;
S.push(u);
for(int i=0;i<(int)G[u].size();++i){
int v=G[u][i];
if(!pre[v]){
dfs(v);
low[u]=min(low[u],low[v]);//用后代的low函数更新自身
}
else if(!sccno[v]){
low[u]=min(low[u],pre[v]);//用反向边更新
}
}
if(low[u]==pre[u]){
++scc_cnt;
for(;;){
int x=S.top();S.pop();
sccno[x]=scc_cnt;
if(x==u) break;
}
}
}
void find_scc(int n){
dfs_clock=scc_cnt=0;
memset(sccno,0,sizeof(sccno));
memset(pre,0,sizeof(pre));
for(int i=0;i<n;++i)
if(!pre[i]) dfs(i);
}
int L[maxm],R[maxm],rsccno[maxn];
int n,m;
int col[maxn],in[maxn];
vector<int> G2[maxn];
void tpsort(int tot)
{
memset(col,-1,sizeof(col));
queue<int> q;
for(int i=1;i<=tot;++i) if(!in[i]) q.push(i);
while(!q.empty())
{
int u=q.front();q.pop();
if(col[u]!=-1) continue;
col[u]=0;col[rsccno[u]]=1;
for(int i=0;i<(int)G2[u].size();++i)
{
--in[G2[u][i]];
if(!in[G2[u][i]]) q.push(G2[u][i]);
}
}
}
int main()
{
int j,i;
while(~scanf("%d%d",&n,&m))
{
if(!n&&!m) break;
for(i=0;i<2*n;++i) G[i].clear();
G[0].push_back(1);
for(i=0;i<m;++i)
{
int A,B;
char a,b;
scanf("%d%c%d%c",&L[i],&a,&R[i],&b);
A=a=='h'?1:0;
B=b=='h'?1:0;
G[2*L[i]+A].push_back(2*R[i]+1-B);
G[2*R[i]+B].push_back(2*L[i]+1-A);
}
find_scc(n<<1);
for(i=0;i<n;++i)
if(sccno[i<<1]==sccno[i<<1|1]) break;
else{
rsccno[sccno[i<<1]]=sccno[i<<1|1];
rsccno[sccno[i<<1|1]]=sccno[i<<1];
}
if(i<n) puts("bad luck");
else{
memset(in,0,sizeof(in));
for(i=1;i<=scc_cnt;++i) G2[i].clear();
for(i=0;i<(n<<1);++i)
for(j=0;j<(int)G[i].size();++j)
if(sccno[i]!=sccno[G[i][j]]){
++in[sccno[G[i][j]]];
G2[sccno[i]].push_back(sccno[G[i][j]]);
}
tpsort(scc_cnt);
int color=col[sccno[0]];
for(i=1;i<n;++i){
if(i!=1) putchar(' ');
if(col[sccno[i<<1]]==color) printf("%dw",i);
else printf("%dh",i);
}
puts("");
}
}
return 0;
}