http://poj.org/problem?id=2723
2-sat 二分
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include<map> #include<queue> #include<stack> #include<cmath> #define LL long long using namespace std; const int N=5000; int head1[N],I1; struct ss { int j,next; }side1[N*50]; struct key { int i,j; }dif[N],eith[N]; int low[N],dfn[N],f[N],deep; bool in[N],visited[N]; stack<int>st; void build1(int x,int y) { side1[I1].j=y; side1[I1].next=head1[x]; head1[x]=I1++; } void Tarjan(int x) { visited[x]=true; in[x]=true; st.push(x); low[x]=dfn[x]=deep++; for(int t=head1[x];t!=-1;t=side1[t].next) { int k=side1[t].j; if(visited[k]==false) { Tarjan(k); low[x]=min(low[x],low[k]); }else if(in[k]==true) { low[x]=min(low[x],dfn[k]); } } if(low[x]==dfn[x]) { int k; do { k=st.top(); st.pop(); in[k]=false; f[k]=x; }while(k!=x); } } bool solve(int m,int n) { memset(head1,-1,sizeof(head1)); I1=0; for(int l=1;l<=n;++l) { build1(dif[l].i,dif[l].j+2*n); build1(dif[l].j,dif[l].i+2*n); } for(int l=1;l<=m;++l) { build1(eith[l].i+2*n,eith[l].j); build1(eith[l].j+2*n,eith[l].i); } memset(visited,false,sizeof(visited)); memset(in,false,sizeof(in)); memset(f,-1,sizeof(f)); while(!st.empty()) st.pop(); deep=0; int l; for(l=0;l<2*n;++l) { if(!visited[l]) Tarjan(l); if(f[l]!=-1&&f[l]==f[l+2*n]) break; } if(l<2*n) return false; else return true; } int main() { //freopen("data.txt","r",stdin); int n,m; while(scanf("%d %d",&n,&m)!=EOF) { if(n==0&&m==0) break; for(int i=1;i<=n;++i) scanf("%d %d",&dif[i].i,&dif[i].j); for(int i=1;i<=m;++i) scanf("%d %d",&eith[i].i,&eith[i].j); int l=1,r=m; while(l<=r) { int mid=(l+r)/2; if(solve(mid,n)) l=mid+1; else r=mid-1; } printf("%d\n",r); } return 0; }