poj2723

题解:

2-sat

二分最后的答案,然后2-sat判断是否可行

代码:

#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int N=10000;
struct rec{int x,y;}p[N],q[N];
int n,m,sum,tot,dfn[N],low[N],belong[N],instack[N];
vector<int> e[N];
stack<int> s;
void tarjan(int u)
{
    int i;
    dfn[u]=low[u]=++tot;
    s.push(u);
    instack[u]=1;
    int size=e[u].size();
    for (i=0;i<size;i++)
     {
        int v=e[u][i];
        if (!dfn[v])
         {
            tarjan(v);
            low[u]=min(low[u],low[v]);
         }
        else if (instack[v]) low[u]=min(low[u],dfn[v]);
     }
    if (dfn[u]==low[u])
     {
        sum++;
        do
         {
            i=s.top();
            s.pop();
            instack[i]=0;
            belong[i]=sum;
         }while (i!=u);
     }
}
int pd(int d)
{
    for (int i=0;i<4*n;i++) e[i].clear();
    for (int i=0;i<n;i++)
     {
        e[q[i].x*2].push_back(q[i].y*2+1);
        e[q[i].y*2].push_back(q[i].x*2+1);
     }
    for (int i=0;i<d;i++)
     {
        e[p[i].x*2+1].push_back(p[i].y*2);
        e[p[i].y*2+1].push_back(p[i].x*2);
     }     
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(instack,0,sizeof(instack));
    memset(belong,0,sizeof(belong));
    sum=tot=0;
    for (int i=0;i<4*n;i++)
     if (!dfn[i]) tarjan(i);
    for (int i=0;i<2*n;i+=2)
     if (belong[i]==belong[i+1]) return 0;
    return 1;
}

int solve()
{
    int l=0,r=m;
    while (l<r)
     {
        int mid=(l+r);
        if (pd(mid))l=mid;
        else r=mid-1;          
     }
    return l;
}

int main()
{
    while (~scanf("%d%d",&n,&m),n||m)
     {
        for (int i=0;i<n;i++)scanf("%d%d",&q[i].x,&q[i].y);
        for (int i=0;i<m;i++)scanf("%d%d",&p[i].x,&p[i].y);
        printf("%d
",solve());                    
     }
    return 0;
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8119387.html