您的位置:首页 > 其它

POJ 2723 Get Luffy Out(2-SAT)

2012-09-11 18:24 309 查看
题意:给你一些钥匙,按顺序有m个门,问最多可以打开多少个门。钥匙是成对的,只能使用一对中的一个钥匙。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
using namespace std;
const int N = 1029;
const int M = 2049;
int n,m;
int hash[N<<2];
struct LT{
    int to,nex;
} L[M<<2];
int F[N<<2],cnt;
void add(int f,int t)
{
    L[cnt].nex =F[f];
    L[cnt].to = t;
    F[f] = cnt++;
}
struct ff{
    int l,r;
} re[M];

void init()
{
    int f,t;
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&f,&t);
        hash[f] = t;hash[t] = f;
    }
    for(int i=0;i<m;i++)
        scanf("%d%d",&re[i].l,&re[i].r);
}
int dfn[N<<2],low[N<<2],col[N<<2],ind,color;
bool post[N<<2];
stack<int> S;
void tdfs(int k){
    dfn[k] = low[k] =ind++;
    post[k] = true;
    S.push(k);
    for(int i=F[k];i;i=L[i].nex){
        int to = L[i].to;
        if(!dfn[to]){
            tdfs(to);
            low[k] = min(low[k],low[to]);
        }else if(post[to]&&low[k]>dfn[to]){
            low[k] = dfn[to];
        }
    }
    if(dfn[k]==low[k]){
        color++;int i;
        for(i=S.top(),S.pop();i!=k;i=S.top(),S.pop())
        {
            col[i] = color; post[i] = false;
        }
        col[i]=color,post[i] = false;
    }
}
bool tarjan()
{
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(col,0,sizeof(col));
    ind=1;color=0;
    for(int i=0;i<(n<<2);i++)
    if(!dfn[i]) tdfs(i);
    for(int i=0;i<(n<<1);i++)
    if(col[i]==col[i+n*2]) return false;
    return true;
}
void solve()
{
    int ans,l=0,r=m,mid;
    while(l<=r)
    {
        mid = (l+r)>>1;
        memset(F,0,sizeof(F));cnt = 1;
        for(int i=0;i<(n<<1);i++)
        add(i,hash[i]+2*n);
        for(int i=0;i<mid;i++)
        if(re[i].l!=re[i].r)
        add(re[i].r+n*2,re[i].l),add(re[i].l+n*2,re[i].r);
        else
        add(re[i].l+n*2,re[i].r);
        if(tarjan())
            ans = mid,l=mid+1;
        else
            r=mid-1;
    }
    printf("%d\n",ans);
}
int main()
{
    freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&m)&&(n+m))
    {
        init();
        solve();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: