• bzoj 1997[Hnoi2010]Planar


    1997: [Hnoi2010]Planar

    Time Limit: 10 Sec  Memory Limit: 64 MB

    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
     
    先根据平面图的性质, e <= 3 * v - 6,  e过大直接就判负了,这样边数是 N^2级别的
    按照2-SAT的建图方法,分为边在环里和边在环外,如果两边在环里相交,就只能一内一外
    所以如果 e[i] 和 e[j] 会在环内相交的话    i -> j'' ,  j'' -> i ,  i'' -> j , j->i'' 分别连边
    然后tarjan 跑强连通,因为这题不用输出方案数,只需要判断  i 和 i'' 是不是在一个强连通分量里就可以了
    判断在环内相交 就是 e[i].u < e[j].u && e[j].u < e[i].v && e[i].v < e[j].v
    这个自己画一画就明白了。
     
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #define LL long long
      6 
      7 using namespace std;
      8 
      9 const int MAXN = 4e2 + 10;
     10 int T, N, M;
     11 
     12 int in[MAXN][MAXN];
     13 int cir[MAXN];
     14 int col[MAXN * MAXN];
     15 int head[MAXN * MAXN];
     16 int ra[MAXN];
     17 int sta[MAXN * MAXN];
     18 int vis[MAXN * MAXN], low[MAXN * MAXN], dfn[MAXN * MAXN];
     19 int top = 0;
     20 int cnt = 0, tot = 0;
     21 struct edge {
     22     int u, v;
     23     int next;
     24 } e[MAXN * MAXN * 4], g[MAXN * MAXN * 4], E[MAXN * MAXN * 4];
     25 
     26 inline LL read()
     27 {
     28     LL x = 0, w = 1; char ch = 0;
     29     while(ch < '0' || ch > '9') {
     30         if(ch == '-') {
     31             w = -1;
     32         }
     33         ch = getchar();
     34     }
     35     while(ch >= '0' && ch <= '9') {
     36         x = x * 10 + ch - '0';
     37         ch = getchar();
     38     }
     39     return x * w;
     40 }
     41 
     42 void DFS(int x)
     43 {
     44     vis[x] = 1;
     45     low[x] = dfn[x] = ++tot;
     46     sta[top++] = x;
     47     for(int j = head[x]; j; j = g[j].next) {
     48         int to = g[j].v;
     49         if(!vis[to]) {
     50             DFS(to);
     51             low[x] = min(low[x], low[to]);
     52         } else if(vis[to] == 1) {
     53             low[x] = min(low[x], dfn[to]);
     54         }
     55     }
     56     if(dfn[x] == low[x]) {
     57         ++cnt;
     58         while(sta[top - 1] != x) {
     59             col[sta[top - 1]] = cnt;
     60             vis[sta[top - 1]] = 2;
     61             top--;
     62         }
     63         col[x] = cnt;
     64         vis[x] = 2;
     65         top--;
     66     }
     67 }
     68 
     69 bool check()
     70 {
     71     for(int i = 1; i <= 2 * M; i++) {
     72         if(!vis[i]) {
     73             DFS(i);
     74         }
     75     }
     76     for(int i = 1; i <= M; i++) {
     77         if(col[i] == col[i + M]) {
     78             return false;
     79         }
     80     }
     81     return true;
     82 }
     83 
     84 void addedge(int u, int v)
     85 {
     86     g[++cnt].next = head[u];
     87     g[cnt].v = v;
     88     head[u] = cnt;
     89 }
     90 
     91 int main()
     92 {
     93 //    freopen("input3.in", "r", stdin); 
     94 //    freopen("t.out", "w", stdout);
     95     T = read();
     96     while(T--) {
     97         memset(vis, 0, sizeof vis);
     98         memset(low, 0, sizeof low);
     99         memset(col, 0, sizeof col);
    100         memset(dfn, 0, sizeof dfn);
    101         memset(head, 0, sizeof head);
    102         memset(in, 0, sizeof in);
    103         memset(cir, 0 , sizeof cir);
    104         memset(ra, 0, sizeof ra);
    105         N = read(), M = read();
    106         tot = 0;
    107         for(int i = 1; i <= M; i++) {
    108             e[i].u = read(), e[i].v = read();
    109         }
    110         for(int i = 1; i <= N; i++) {
    111             int num = read();
    112             ra[num] = i;
    113             cir[i] = num;
    114         }
    115         if(M > 3 * N + 6) {
    116             printf("NO
    ");
    117             continue;
    118         }
    119         /*if(T == 1) {
    120             cout<<N<<" "<<
    121             for(int i = 1; i <= N; i++)
    122             cout<<cir[i]<<" ";
    123                     cout<<endl<<endl; 
    124         }*/
    125         for(int i = 1; i <= N; i++) {
    126             in[cir[i]][cir[i % N + 1]] = in[cir[i % N + 1]][cir[i]] = 1;
    127         }
    128         for(int i = 1; i <= M; i++) {
    129             if(in[e[i].u][e[i].v] == 1) {
    130                 continue;
    131             }
    132             if(ra[e[i].u] > ra[e[i].v]) {
    133                 swap(e[i].u, e[i].v);
    134             }
    135             E[++tot].u = e[i].u, E[tot].v = e[i].v;
    136         }
    137         M = tot;
    138         cnt = 0;
    139     /*    if(T == 1) {
    140         cout<<endl;
    141         for(int i = 1; i <= M; i++) {
    142             cout<<E[i].u<<" "<<E[i].v<<" "<<ra[E[i].u]<<" "<<ra[E[i].v]<<endl;
    143         }
    144         cout<<endl;
    145         }*/
    146         for(int i = 1; i < M; i++) {
    147             for(int j = i + 1; j <= M; j++) {
    148                 int u = ra[E[i].u], v = ra[E[i].v], x = ra[E[j].u], y = ra[E[j].v];
    149                 if((u < x && x < v && v < y) || (u > x && y > u && v > y)) {
    150                     addedge(i, j + M);
    151                     addedge(i + M, j);
    152                     addedge(j, i + M);
    153                     addedge(j + M, i);
    154                 }
    155             }
    156         }
    157     /*    for(int i = 1; i <= M; i++) {
    158             cout<<i<<endl;
    159             for(int j = head[i]; j; j = g[j].next) {
    160                 int to = g[j].v;
    161                 cout<<to<<" ";
    162             }
    163             cout<<endl<<endl;
    164         }*/
    165         tot = 0, cnt = 0;
    166         if(check()) {
    167             printf("YES
    ");
    168         } else {
    169             printf("NO
    ");
    170         }
    171     }
    172 }
    View Code
  • 相关阅读:
    UILabel 自适应大小
    CGAffineTransformScale
    CAKeyframeAnimation
    CABasicAnimation
    IOS 动画
    xcode 怎么样在发布release版本的时候 不输出log
    [转贴] C++ 判断主机是否处于联网状态下
    [转贴] 从零开始学C++之异常(二):程序错误、异常(语法、抛出、捕获、传播)、栈展开
    [转贴]从零开始学C++之异常(一):C语言错误处理方法、C++异常处理方法(throw, try, catch)简介
    [转贴]gsoap使用心得!
  • 原文地址:https://www.cnblogs.com/wuenze/p/8666795.html
Copyright © 2020-2023  润新知