poj 3648
2sat,注意题意。
代码:
#include<iostream> #include<fstream> using namespace std; struct e{ int data; e *next; }edge[121],edge2[122]; int n,m; int v[121],low[121],dfn[121],stack[121],scc[121],tot,index,top; void tarjan(int s){ int i,j,k; dfn[s]=low[s]=++index; stack[++top]=s; v[s]=1; e *p=edge[s].next; while(p){ if(dfn[p->data]==0) { tarjan(p->data); low[s]=min(low[s],low[p->data]); } else if(v[p->data]) { low[s]=min(low[s],dfn[p->data]); } p=p->next; } if(low[s]==dfn[s]){ ++tot; do{ i=stack[top--]; scc[i]=tot; v[i]=0; }while(i!=s); } } void solve(){ int i,j,k; index=0;tot=0;top=0; memset(v,0,sizeof(v)); memset(dfn,0,sizeof(dfn)); for(i=0;i<4*n;i++) if(dfn[i]==0) tarjan(i); } void build(){ int i,j,k; memset(edge2,0,sizeof(edge2)); for(i=0;i<4*n;i++) { e *p=edge[i].next; while(p){ if(scc[p->data]!=scc[i]) { e *q=new e; q->data=scc[i]; q->next=edge2[scc[p->data]].next; edge2[scc[p->data]].next=q; } p=p->next; } } } int queue[130]; void dfs(int s){ int i,j,k; v[s]=1; e *p=edge2[s].next; while(p){ if(v[p->data]==0) dfs(p->data); p=p->next; } queue[top++]=s; } int ant[130]; void solve1(){ int i,j,k; for(i=0;i<2*n;i++) { ant[scc[i]]=scc[i+2*n]; ant[scc[i+2*n]]=scc[i]; } build(); top=0; for(i=0;i<tot;i++) if(v[i]==0) dfs(i); memset(v,0,sizeof(v)); for(i=top-1;i>=0;i--) { j=queue[i]; if(v[j]==0) { v[j]=1; v[ant[j]]=2; j=ant[j]; e *p=edge2[j].next; while(p){ v[p->data]=2; p=p->next; } } } for(i=1;i<n;i++) if(v[scc[i]]==1) cout<<i<<"w "; for(i=n;i<2*n;i++) if(v[scc[i]]==1) cout<<i-n<<"h "; cout<<endl; } void read(){ // ifstream cin("in.txt"); int i,j,k,s; while(1){ cin>>n>>m; if(n==0&&m==0) return; memset(edge,0,sizeof(edge)); s=2*n; e *p=new e; p->data=0; p->next=edge[n].next; edge[n].next=p; e *q=new e; q->data=3*n; q->next=edge[2*n].next; edge[2*n].next=q; for(i=0;i<n;i++) { e *p=new e; p->data=i+s; p->next=edge[i+n].next; edge[i+n].next=p; e*q=new e; q->data=i; q->next=edge[i+n+s].next; edge[i+n+s].next=q; e*p1=new e; p1->data=i+n; p1->next=edge[i+s].next; edge[i+s].next=p1; e *q1=new e; q1->data=i+n+s; q1->next=edge[i].next; edge[i].next=q1; } char c1,c2; for(i=1;i<=m;i++) { cin>>j>>c1>>k>>c2; if(c1=='h') j+=n; if(c2=='h') k+=n; e *p=new e; p->data=k; p->next=edge[j+s].next; edge[j+s].next=p; e *q=new e; q->data=j; q->next=edge[k+s].next; edge[k+s].next=q; } solve(); for(i=1;i<=n*2;i++) if(scc[i]==scc[i+s]) break; if(i<=n*2) { cout<<"bad luck"<<endl; continue; } else { solve1(); } } } int main(){ read(); return 0; }