poj 2723 Get Luffy Out

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;

}

  

你可能感兴趣的:(get)