poj 2723 Get Luffy Out

来源:互联网 发布:西安万科金域名城哪儿 编辑:程序博客网 时间:2024/06/05 17:40

有n对钥匙,每对钥匙只能开一个门,有m个门,只能按顺序1到m的打开,每个门上有两把锁,打开其中一把就可开门,输出最多可以开多个门。

二分开门的个数,加入门有锁2,3,钥匙1,2,和3,4那么2,与3矛盾,1,与4矛盾。应1,3连边,2,4连边,判断是否可行。

#include <iostream>#include <cstdio>#include <vector>#include <cmath>#include <stack>#include <map>#include <set>#include <queue>#include <cstring>#include <algorithm>using namespace std;#define L(t) t<<1#define R(t) t<<1|1#define eps 1e-7typedef long long LL;const int maxn=4050;const int maxm=10005;const int MOD=1000000007;int pa[maxn];int x[maxn],y[maxn];int dfn[maxn],low[maxn],head[maxn],next[maxm],to[maxm],stk[maxn],id[maxn];bool vis[maxn];int n,m,top,cnt,tot,scc;void init(){    top=tot=scc=0;    cnt=1;    memset(vis,0,sizeof(vis));    memset(dfn,0,sizeof(dfn));    memset(head,-1,sizeof(head));}void addEdge(int u,int v){    next[tot]=head[u],to[tot]=v,head[u]=tot++;}void tarjan(int v){    dfn[v]=low[v]=cnt++;    vis[v]=1;    stk[++top]=v;    for(int i=head[v];i!=-1;i=next[i])    {        int u=to[i];        if(!dfn[u])        {            tarjan(u);            low[v]=min(low[v],low[u]);        }        else if(vis[u])        {            low[v]=min(low[v],dfn[u]);        }    }    if(dfn[v]==low[v])    {        scc++;        int u;        do        {            u=stk[top--];            id[u]=scc;            vis[u]=0;        }while(u!=v);    }}bool judge(int k){    init();    for(int i=0;i<k;i++)    {        addEdge(x[i],pa[y[i]]);        addEdge(y[i],pa[x[i]]);    }    for(int i=0;i<2*n;i++)    {//        top=0;        if(!dfn[i])            tarjan(i);    }    for(int i=0;i<n;i++)    {        if(id[i]==id[pa[i]])        {            return false;        }    }    return true;}int main(){    //freopen("in.txt","r",stdin);    while(scanf("%d%d",&n,&m)&&(n+m))    {        for(int i=0,u,v;i<n;i++)        {            scanf("%d%d",&u,&v);            pa[u]=v,pa[v]=u;        }        for(int i=0;i<m;i++)        {            scanf("%d%d",&x[i],&y[i]);        }        int l=0,r=m+1,mid;        while(l+1<r)        {            mid=(l+r)>>1;            if(judge(mid))            {                l=mid;            }            else            {                r=mid;            }        }        printf("%d\n",l);    }    return 0;}