zoukankan      html  css  js  c++  java
  • [BZOJ1997] [Hnoi2010]Planar

    1997: [Hnoi2010]Planar

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 2639  Solved: 1015
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    2
    6 9
    1 4
    1 5
    1 6
    2 4
    2 5
    2 6
    3 4
    3 5
    3 6
    1 4 2 5 3 6
    5 5
    1 2
    2 3
    3 4
    4 5
    5 1
    1 2 3 4 5

    Sample Output

    NO
    YES

    HINT


    题解:

    2—SAT裸题...

    如果两条边i,j有相交,那么我们创造一个命题"如果i则~j",逆否命题"如果j则~i",然后裸了...


    Code

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    using namespace std;
    int T, n, m; 
    int L[10010], R[10010], num;
    struct edge{
        int nxt,to;
    }ed[1000005];
    int head[5005], cnt = 1;
    inline void add(int x, int y){ed[++cnt]=(edge){head[x],y};head[x]=cnt;}
    int dfn[5005], low[5005], dfnn;
    int stack[5005], top, C[5005], scc;
    bool ins[5005];
    int pos[5005], D[5005];
    void Tarjan(int x)
    {
        dfn[x] = low[x] = ++dfnn;
        stack[++top] = x, ins[x] = 1;
        for (register int i = head[x] ; i ; i = ed[i].nxt)
        {
            int to = ed[i].to;
            if (!dfn[to]){Tarjan(to);low[x]=min(low[x],low[to]);}
            else if(ins[to]) low[x] = min(low[x], low[to]);
        }
        if (dfn[x] == low[x])
        {
            scc++;int y;
            do{
                y = stack[top--], ins[y] = 0;
                C[y] = scc;
            }while(y != x);
        }
    }
    inline void init()
    {    
        cnt=1;top=0;dfnn=0;num=0;scc=0;
        memset(ins, 0, sizeof ins);
        memset(C, 0, sizeof C);
        memset(head, 0, sizeof head);
        memset(stack, 0, sizeof stack);
        memset(pos, 0, sizeof pos);
        memset(dfn, 0, sizeof dfn);
        memset(low, 0, sizeof low);
        memset(D, 0, sizeof D);
    //    cleann(ins, 0), cleann(C, 0), cleann(head, 0), cleann(stack, 0);
    //    cleann(pos, 0), cleann(dfn, 0), cleann(low, 0),cleann(D, 0);
    }
    int main()
    {
        scanf("%d", &T);
        while (T--)
        {
            init();
            scanf("%d%d", &n, &m);
            for (register int i = 1 ; i <= m ; i ++) 
                scanf("%d%d", &L[i], &R[i]);
            for (register int i = 1 ; i <= n ; i ++)
                scanf("%d", &D[i]);
            if (m > 3 * n - 6) {puts("NO");continue;}
            for (register int i = 1 ; i <= n ; i ++)
                pos[D[i]] = i;
            for (register int i = 1 ; i <= m ; i ++)
            {
                R[i] = pos[R[i]], L[i] = pos[L[i]];
                if (R[i] < L[i]) swap(R[i], L[i]);//R[i] > L[i]
                if (R[i] - L[i] == 1 or (R[i] == n and L[i] == 1)) continue;
                L[++num] = L[i], R[num] = R[i];
            }
            for (register int i = 1 ; i <= num ; i ++)
            {
                for (register int j = 1 ; j <= num ; j ++)
                {
                    if (i == j) continue;
                    if ((L[i] > L[j] and R[j] > L[i] and R[j] < R[i]) or (L[i] < L[j] and R[j] > R[i] and R[i] > L[j]))
                    {
                        add(i , j + num);
                        add(j + num, i);
                    }
                }
            }
            for (register int i = 1 ; i <= 2 * num ; i ++) if (!dfn[i]) Tarjan(i);
            bool flag = 0;
            for (register int i = 1 ; i <= num ; i ++)
            {
                if (C[i] == C[i + num]) {puts("NO");flag = 1;break;}
            }
            
            if (!flag)puts("YES");
        }
    }
  • 相关阅读:
    新学期——扬帆起航
    我与虚拟机的爱恨情仇
    20155329胡佩伦的第二次预备作业——再思考
    课前的第一次与老师交流
    # 20155327 2016-20017-3 《Java程序设计》第3周学习总结
    20155327《Java程序设计》第二周学习总结
    20155327 2016-2017-2 《Java程序设计》第一周学习总结
    20155327第三次作业
    20155327 学习基础和C语言基础调查
    记自己的第一篇博客
  • 原文地址:https://www.cnblogs.com/BriMon/p/9278773.html
Copyright © 2011-2022 走看看