zoukankan      html  css  js  c++  java
  • POJ3207(2-SAT+模型3)

    题目链接:https://vjudge.net/problem/POJ-3207

    题目意思:有一个圆,给出一些边连接着两个点,边可以从圆里连,也可以从圆外连,问是否可以不相交

    对于边i,ji,j限制条件为不相交,即不在同一个集合中

    因此我们将这个问题转化为了2-SAT问题

    ii表示边ii在圆内,ii′表示ii在圆外

    (i,j)(i,j)在圆内相交,那么它们在圆外也一定相交

    如果边i,ji,j在圆内相交

    那么就从ii连向jj′(i内j外),从jj′连向ii(i内j外),从jj连向ii′(j内i外),从ii′连向jj(j内i外)

    然后来一遍tarjan就好了

     

     1 #include<cstdio>
     2 #include<string.h>
     3 #include<vector>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N = 1000005;
     7 int n,m,cnt,tot,top,scc,dfn[N],low[N],vis[N],sta[N],S[N],T[N],belong[N];
     8 vector<int> G[2*N];
     9 void init()
    10 {
    11     memset(dfn,0,sizeof(dfn));
    12     memset(low,0,sizeof(low));
    13     memset(vis,0,sizeof(vis));
    14     memset(sta,0,sizeof(sta));
    15     memset(belong,0,sizeof(belong));
    16     cnt = tot = top = scc = 0;
    17 }
    18 void add(int u,int v)
    19 {
    20     G[u].push_back(v);
    21 }
    22 void tarjan(int u)
    23 {
    24     dfn[u]  = low[u] = ++cnt;
    25     vis[u] = 1;
    26     sta[top++] = u;
    27     for(int i = 0; i < G[u].size();i ++)
    28     {
    29         int v = G[u][i];
    30         if(!dfn[v])
    31         {
    32             tarjan(v);
    33             low[u] = min(low[u],low[v]);
    34         }
    35         else if(vis[v])
    36         {
    37             low[u] = min(low[u],dfn[v]);
    38         }
    39     }
    40     if(dfn[u] == low[u])
    41     {
    42         int t;
    43         ++scc;
    44         do
    45         {
    46             t = sta[--top];
    47             vis[t] = 0;
    48             belong[t] = scc;
    49         }while(t != u);
    50     }
    51 }
    52 int main()
    53 {
    54     scanf("%d%d",&n,&m);
    55     init();
    56     for(int i = 0;i < m;i ++)
    57     {
    58         scanf("%d%d",&S[i],&T[i]);
    59         if(S[i] > T[i]) swap(S[i],T[i]);
    60     }
    61     for(int i = 0;i < m;i ++)
    62     {
    63         for(int j = i + 1;j < m;j++)
    64         {
    65             if(S[i] < S[j] && S[j] < T[i] && T[i] < T[j]||S[j] < S[i] && S[i] < T[j] && T[j] < T[i])
    66             {
    67                 add(i,j + m);
    68                 add(j + m,i);
    69                 add(j,i + m);
    70                 add(i + m,j);
    71             }
    72         }
    73     }
    74     for(int i = 0; i < (m<<1);i ++)
    75     {
    76         if(!dfn[i]) tarjan(i);
    77     }
    78     for(int i = 0;i < m;i ++)
    79     {
    80         if(belong[i] == belong[i+m])
    81         {
    82             printf("the evil panda is lying again
    ");
    83             return 0;
    84         }
    85     }
    86     printf("panda is telling the truth...
    ");
    87     return 0;
    88  } 
  • 相关阅读:
    1295. 统计位数为偶数的数字『简单』
    1281. 整数的各位积和之差『简单』
    697. 数组的度『简单』
    748. 最短完整词『简单』
    832. 翻转图像『简单』
    1446. 连续字符『简单』
    1455. 检查单词是否为句中其他单词的前缀『简单』
    1160. 拼写单词『简单』
    1304. 和为零的N个唯一整数『简单』
    1103. 分糖果 II『简单』
  • 原文地址:https://www.cnblogs.com/Mingusu/p/12548874.html
Copyright © 2011-2022 走看看