zoukankan      html  css  js  c++  java
  • poj3683

    2-SAT算法流程

    1.建立选择边

    2.tarjan缩点(同一块内必然同时选择),判断是否存在可行解(若存在一对对立点{2*i,2*i-1}在同一块内,则不可行)

    3.把缩点后的块之间建立反向选择边,并传递不选择命令(code中用op[ ]数组记录)

    4.按照拓扑序找到一为选择的点(块),标为选择,传递不选择标记

    //poj3683
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define inf 2000000000
    #define ll long long 
    #define mod 1000000007
    using namespace std;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,cnt,top,scc,ind;
    int a[2005],b[2005],belong[2005],op[2005];
    int dfn[2005],low[2005],q[2005];
    bool inq[2005];
    struct edge{int to,next;}e[2000005],ed[2000005];
    int last[2005],last2[2005],d[2005];
    int color[2005];
    bool jud(int x,int y){
        if(b[x]<=a[y]||a[x]>=b[y])return 0;
        return 1;
    }
    void insert(int u,int v){e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;}
    void insert2(int u,int v){d[v]++;ed[++cnt].to=v;ed[cnt].next=last2[u];last2[u]=cnt;}
    void build(){
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++){
                if(jud(2*i,2*j)){insert(2*i,2*j-1);insert(2*j,2*i-1);}
                if(jud(2*i,2*j-1)){insert(2*i,2*j);insert(2*j-1,2*i-1);}
                if(jud(2*i-1,2*j)){insert(2*i-1,2*j-1);insert(2*j,2*i);}
                if(jud(2*i-1,2*j-1)){insert(2*i-1,2*j);insert(2*j-1,2*i);}
            }
    }
    void tarjan(int x){
        dfn[x]=low[x]=++ind;
        q[++top]=x;inq[x]=1;
        for(int i=last[x];i;i=e[i].next)
            if(!dfn[e[i].to]){tarjan(e[i].to);low[x]=min(low[e[i].to],low[x]);}
            else if(inq[e[i].to])low[x]=min(dfn[e[i].to],low[x]);
        if(low[x]==dfn[x]){
            int now=0;scc++;
            while(now!=x){
                now=q[top--];
                inq[now]=0;
                belong[now]=scc;
            }
        }
    }
    void rebuild(){
        cnt=0;
        for(int x=1;x<=2*n;x++)
            for(int i=last[x];i;i=e[i].next)
                if(belong[x]!=belong[e[i].to])
                    insert2(belong[e[i].to],belong[x]);
    }
    void dfs(int x){
        if(color[x])return;
        color[x]=-1;
        for(int i=last2[x];i;i=ed[i].next)dfs(ed[i].to);
    }
    void topsort(){
        for(int i=1;i<=scc;i++)if(!d[i])q[++top]=i;
        while(top){
            int now=q[top--];
            if(color[now])continue;
            color[now]=1;dfs(op[now]);
            for(int i=last2[now];i;i=ed[i].next){
                d[ed[i].to]--;
                if(!d[ed[i].to])q[++top]=ed[i].to;
            }
        }
    }
    void print(int x){printf("%.2d:",x/60);printf("%.2d ",x%60);}
    int main(){
        n=read();
        int x;
        for(int i=1;i<=n;i++){
            a[2*i]=read();a[2*i]=a[2*i]*60+read();
            b[2*i-1]=read();b[2*i-1]=b[2*i-1]*60+read();
            x=read();b[2*i]=a[2*i]+x;a[2*i-1]=b[2*i-1]-x;
        }
        build();
        for(int i=1;i<=2*n;i++)if(!dfn[i])tarjan(i);
        for(int i=1;i<=n;i++)
            if(belong[2*i]==belong[2*i-1]){puts("NO");return 0;}
        puts("YES");
        rebuild();
        for(int i=1;i<=n;i++){
            op[belong[2*i]]=belong[2*i-1];
            op[belong[2*i-1]]=belong[2*i];
        }
        topsort();
        for(int i=1;i<=n;i++)
            if(color[belong[2*i]]==1)
                print(a[2*i]),print(b[2*i]),puts("");
            else print(a[2*i-1]),print(b[2*i-1]),puts("");
        return 0;
    }
  • 相关阅读:
    Python笔记(六)- 模型及Django站点管理
    Python笔记(五)--Django中使用模板
    Java中对象的复制
    Echarts堆积柱状图排序问题
    java基础
    java中的重载与重写
    struts2中配置文件的调用顺序
    struts2的工作原理
    拦截器和过滤器的区别
    Struts2中访问web元素的四种方式
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/9256736.html
Copyright © 2011-2022 走看看