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

    1997: [Hnoi2010]Planar

    链接

    分析:

      首先在给定的那个环上考虑进行操作,如果环内有有两条边相交,那么可以把其中的一条放到环的外面去。所以转换为2-sat问题。

    像这样,由于1-4和2-3在环内相交了,所以可以把1-4放到环外,就变成了下图。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 1205;
    struct Edge{ int to, nxt; } e[2000005];
    int head[N], dfn[N], low[N], bel[N], sk[N], c[N], pos[N], top, Index, tot, En;
    bool vis[N];
    pair<int,int> g[10005];
    
    inline void add_edge(int u,int v) {
        ++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
    }
    void tarjan(int u) {
        low[u] = dfn[u] = ++Index;
        sk[++top] = u; vis[u] = 1;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            if (vis[v]) low[u] = min(low[u], dfn[v]);
        }
        if (low[u] == dfn[u]) {
            ++tot;
            do {
                vis[sk[top]] = 0;
                bel[sk[top]] = tot;
                top --;
            } while (sk[top + 1] != u);
        }
    }
    bool judge(int a,int b,int c,int d) {
        if (b > c && b < d && a < c) return 1;
        if (a > c && a < d && b > d) return 1;
        return 0;
    }
    void solve() {
        int n = read(), m = read(), cnt = 0;
        for (int i = 1; i <= m; ++i) 
            g[i].first = read(), g[i].second = read();
        for (int i = 1; i <= n; ++i) c[i] = read();
        if (m > 3 * n - 6) { puts("NO"); return ; }
        for (int i = 1; i <= n; ++i) pos[c[i]] = i;
        for (int i = 1; i <= m; ++i) {
            g[i].first = pos[g[i].first], g[i].second = pos[g[i].second];
            if (g[i].first > g[i].second) swap(g[i].first, g[i].second);
            if (g[i].second - g[i].first == 1 || (g[i].first == 1 && g[i].second == n)) continue;
            g[++cnt] = g[i];
        }
        m = cnt;
        for (int i = 1; i <= m; ++i) 
            for (int j = i + 1; j <= m; ++j) {
                if (judge(g[i].first, g[i].second, g[j].first, g[j].second)) {
                    add_edge(i, j + m);
                    add_edge(i + m, j);
                    add_edge(j, i + m);
                    add_edge(j + m, i);
                }
            }
        for (int i = 1; i <= m + m; ++i) if (!dfn[i]) tarjan(i);
        bool flag = 1;
        for (int i = 1; i <= m; ++i) if (bel[i] == bel[i + m]) flag = 0;
        puts(flag ? "YES" : "NO");
        top = Index = En = tot = 0;
        for (int i = 0; i <= m + m; ++i) 
            head[i] = dfn[i] = low[i] = bel[i] = 0;
    }
    int main() {
        for (int T = read(); T--; ) solve();
        return 0;
    }
  • 相关阅读:
    cocos2dx打包apk
    cocos2d 小游戏
    排序算法笔记二
    把一张合成图分拆出各个小图
    出栈入栈动画demo
    Android 面試題
    AS项目删减打包-01
    c程序指针题
    ubuntu14.04 设置默认登录用户为root
    Ubuntu14.04 Java环境变量配置
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10291140.html
Copyright © 2011-2022 走看看