题意怪怪的,还不给输入规模_(: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; }