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;
}
浙公网安备 33010602011771号