poj 2723 2-SAT

来源:互联网 发布:2017最新seo 编辑:程序博客网 时间:2024/06/07 19:30

题意:有n对钥匙,有m个门,每个门可以有2把钥匙打开,但是通关是一个一个门进行的,从n对里面,选择n把钥匙,最多可以打开几个门?

解法:2-SAT

            枚举可以打开几个门,然后用2-SAT判断是否可行。

/*----------------------------------   Love is more than a word.   It says so much.   When I see these four letters,   I almost feel your touch.   This is only happened since   I fell in love with you.   Why this word does this,   I haven't got a clue.                   To My Goddess                          CY----------------------------------*/#include<iostream>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#include<cmath>#include<stdlib.h>#include<iomanip>#include<list>#include<deque>#include<map>#include <stdio.h>#include <queue>#define maxn 500000+5#define ull unsigned long long #define ll long long#define reP(i,n) for(i=1;i<=n;i++) #define REP(i,a,b) for(i=a;i<=b;i++)  #define rep(i,n) for(i=0;i<n;i++)#define cle(a) memset(a,0,sizeof(a)) #define clehead(a) rep(i,maxn)a[i]=-1/*  The time of story :  **  while(1)    {         once upon a time,         there was a mountain,         on top of which there was a temple,         in which there was an old monk and a little monk.         Old monk was telling stories inside the temple.         What was he talking about?  **  }   ÎûÎû   (*^__^*)*/#define sci(a) scanf("%d",&a) #define scd(a) scanf("%lf",&a)  #define pri(a) printf("%d",a)   #define prie(a) printf("%d\n",a)    #define prd(a)  printf("%lf",a)     #define prde(a) printf("%lf\n",a)      #define pre printf("\n")#define LL(x) x<<1 #define RR(x) x<<|1#define pb push_back#define mod 90001#define PI 3.141592657const ull INF = 1LL << 61;const int inf =   int(1e5)+10;const double eps=1e-5;using namespace std;int n,m;    struct node    {        int be;       int to,w;       int next;    }edge[maxn];    node nn[maxn];    node mm[maxn];    bool cmp(int a,int b){        return a>b;    }    node cop[maxn];    int head[maxn];    int low[maxn],dfn[maxn],stack[maxn],used[maxn];    int cnt=0;    int in[maxn],out[maxn];    void add(int x,int y)    {        edge[cnt].be=x;        edge[cnt].to=y;        edge[cnt++].next=head[x];        head[x]=(cnt-1);    }    void init()    {        memset(head,-1,sizeof(head));        cle(used),cle(low),cle(dfn),cle(in),cle(out);        m=0;        cnt=0;    }    int tarbfs(int k,int lay,int &scc_num)    {        used[k]=1;        low[k]=lay;        dfn[k]=lay;        stack[++m]=k;        for(int i=head[k];i!=-1;i=edge[i].next)        {            if(used[edge[i].to]==0)            {                tarbfs(edge[i].to,++lay,scc_num);            }            if(used[edge[i].to]==1)            {                low[k]=min(low[k],low[edge[i].to]);            }        }        if(dfn[k]==low[k])        {            ++scc_num;            do{                low[stack[m]]=scc_num;                used[stack[m]]=2;            }while(stack[m--]!=k);        }        return 0;    }int build(int len){    int i,j,k;    init();    rep(i,n){        add(nn[i].be,nn[i].to+(2*n));        add(nn[i].to,nn[i].be+(2*n));    }    rep(i,len){         add(mm[i].be+(2*n),mm[i].to);         add(mm[i].to+(2*n),mm[i].be);    }    int lay=1;    int scc_num=0;    rep(i,2*n){       if(!used[i])tarbfs(i,lay,scc_num);    }    rep(i,2*n){       // cout<<low[i]<<":"<<low[i+2*n]<<endl;        if(low[i]==low[i+2*n])        {            //cout<<111<<endl;            return false;        }    }    return true;}int main(){    freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    while(scanf("%d%d",&n,&m)!=EOF)    {        if(n==0&&m==0)break;        int i,j,k;        rep(i,n)        {            scanf("%d%d",&nn[i].be,&nn[i].to);        }        rep(i,m)scanf("%d%d",&mm[i].be,&mm[i].to);        int mid=0;        int ans=0;        int l=0,r=m;        while(l<=r)        {            mid=(l+r)>>1;            if(build(mid)){                l=mid+1;                ans=max(ans,mid);            }            else r=mid-1;        }        printf("%d\n",ans);    }    return 0;}


0 0