• BZOJ 1997: [Hnoi2010]Planar( 2sat )


    平面图中E ≤ V*2-6..

    一个圈上2个点的边可以是在外或者内, 经典的2sat问题..

    ------------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<stack>
     
    using namespace std;
     
    #define U(x) U[r[x]]
    #define V(x) V[r[x]]
    #define H(x) H[r[x]]
     
    const int maxn = 20009;
     
    struct edge {
    int to;
    edge* next;
    } E[1000000], *pt, *head[maxn];
     
    void AddEdge(int u, int v) {
    pt->to = v; pt->next = head[u]; head[u] = pt++;
    }
     
    int Low[maxn], Dfn[maxn], Scc[maxn], CK, scc_n;
    int U[maxn], V[maxn], H[maxn], P[maxn], _P[maxn], r[maxn], n;
    int N, M, T;
    stack<int> S;
     
    void Init() {
    pt = E;
    memset(head, 0, sizeof head);
    scanf("%d%d", &N, &M);
    for(int i = 0; i < M; i++)
    scanf("%d%d", U + i, V + i);
    for(int i = 0; i < N; i++) {
    scanf("%d", _P + i);
    P[_P[i]] = i;
    }
    for(int i = 0; i < N; i++)
    H[_P[i]] = _P[(i + 1) % N];
    n = scc_n = CK = 0;
    memset(Dfn, 0, sizeof Dfn);
    memset(Scc, 0, sizeof Scc);
    while(!S.empty()) S.pop();
    }
     
    bool chk(int l, int r, int _l, int _r) {
    if(l > r) swap(l, r);
    if(_l > _r) swap(_l, _r);
    return (l < _l && _l < r && r < _r) || (_l < l && l < _r && _r < r);
    }
     
    void Tarjan(int x) {
    Dfn[x] = Low[x] = ++CK;
    S.push(x);
    for(edge* e = head[x]; e; e = e->next) if(!Dfn[e->to]) {
    Tarjan(e->to);
    Low[x] = min(Low[x], Low[e->to]);
    } else if(!Scc[e->to])
    Low[x] = min(Low[x], Dfn[e->to]);
    if(Dfn[x] == Low[x]) {
    int t; scc_n++;
    do {
    t = S.top(); S.pop();
    Scc[t] = scc_n;
    } while(t != x);
    }
    }
     
    bool Solve() {
    if(M > 3 * N - 6) return false;
    for(int i = 0; i < M; i++)
    if(V[i] != H[U[i]] && U[i] != H[V[i]]) r[n++] = i;
    for(int i = 0; i < n; i++)
    for(int j = 0; j < i; j++)
    if(chk(P[U(i)], P[V(i)], P[U(j)], P[V(j)])) {
    AddEdge(i * 2, j * 2 + 1);
    AddEdge(i * 2 + 1, j * 2);
    AddEdge(j * 2, i * 2 + 1);
    AddEdge(j * 2 + 1, i * 2);
    }
    for(int i = 0; i < 2 * n; i++) {
    if(!Dfn[i]) Tarjan(i);
    }
    for(int i = 0; i < n; i++)
    if(Scc[i * 2] == Scc[i * 2 + 1]) return false;
    return true;
    }
     
    int main() {
    scanf("%d", &T);
    while(T--) {
    Init();
    puts(Solve() ? "YES" : "NO");
    }
    return 0;
    }

    ------------------------------------------------------------------------------------------

    1997: [Hnoi2010]Planar

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1183  Solved: 458
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    Sample Output

    HINT

    Source

  • 相关阅读:
    .NET 动态脚本语言
    webParts与Web部件
    比较JqGrid与XtraGrid
    XtraGrid滚轮翻页
    Python------继承
    Python 私有化类的属性
    Python print 输出不换行,只有空格
    Python--函数参数类型
    手推FP-growth (频繁模式增长)算法------挖掘频繁项集
    Python 返回多个值+Lambda的使用
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5011278.html
Copyright © 2020-2023  润新知