• poj 3207(2-SAT+SCC)


    传送门:Problem 3207

    https://www.cnblogs.com/violet-acmer/p/9769406.html

    难点:

      题意理解。

    题意:

      平面上有一个圆,圆上有n个点(分别编号0-n-1,按顺序在圆上排列),现在要对这n个点连接m条线,这m条线的两个端点已经给出了,这个线可以从圆内连或从圆外连,且任意一个点最多只作为一条线的端点.要求任意两条线不相交,问你是否可能?

      注意:两点间的连线没说一定是直线。

    题解:

      两直线ab,cd(a < b , c < d)不可以同时在圆内或圆外的条件是 a<c<b<d || c<a<d<b

      以此构造布尔方程。

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<vector>
     4 #include<cstring>
     5 using namespace std;
     6 #define pb push_back
     7 #define mem(a,b) (memset(a,b,sizeof a))
     8 const int maxn=500+50;
     9 
    10 int n,m;
    11 int a[maxn],b[maxn];
    12 int scc[2*maxn];
    13 bool vis[2*maxn];
    14 vector<int >vs;
    15 vector<int >G[2*maxn],rG[2*maxn];
    16 void addEdge(int u,int v)
    17 {
    18     G[u].pb(v);
    19     rG[v].pb(u);
    20 }
    21 bool Touch(int a,int b,int c,int d)//判断 ab 是否一定与 cd 相交
    22 {
    23     if(a<c && c<b && b<d)
    24         return true;
    25     if(c<a && a<d && d<b)
    26         return true;
    27     return false;
    28 }
    29 void Dfs(int u)
    30 {
    31     vis[u]=true;
    32     for(int i=0;i < G[u].size();++i)
    33     {
    34         int to=G[u][i];
    35         if(!vis[to])
    36             Dfs(to);
    37     }
    38     vs.pb(u);
    39 }
    40 void rDfs(int u,int k)
    41 {
    42     vis[u]=true;
    43     scc[u]=k;
    44     for(int i=0;i < rG[u].size();++i)
    45     {
    46         int to=rG[u][i];
    47         if(!vis[to])
    48             rDfs(to,k);
    49     }
    50 }
    51 void SCC()
    52 {
    53     mem(vis,false);
    54     vs.clear();
    55     for(int i=1;i <= 2*m;++i)
    56         if(!vis[i])
    57             Dfs(i);
    58     mem(vis,false);
    59     int k=0;
    60     for(int i=vs.size()-1;i >= 0;--i)
    61     {
    62         int to=vs[i];
    63         if(!vis[to])
    64             rDfs(to,++k);
    65     }
    66 }
    67 int main()
    68 {
    69     scanf("%d%d",&n,&m);
    70     for(int i=1;i <= m;++i)
    71     {
    72         scanf("%d%d",a+i,b+i);
    73         if(a[i] > b[i])
    74             swap(a[i],b[i]);
    75         for(int j=1;j < i;++j)
    76         {
    77             if(Touch(a[i],b[i],a[j],b[j]))
    78             {
    79                 addEdge(j+m,i);
    80                 addEdge(i+m,j);
    81                 addEdge(j,i+m);
    82                 addEdge(i,j+m);
    83             }
    84         }
    85     }
    86     SCC();
    87     bool flag=false;
    88     for(int i=1;i <= m;++i)
    89         if(scc[i] == scc[i+m])
    90             flag=true;
    91     if(flag)
    92         printf("the evil panda is lying again
    ");
    93     else
    94         printf("panda is telling the truth...
    ");
    95 }
    View Code
  • 相关阅读:
    NJUPT_Wrj 个人训练实录
    图片保存本地,上传阿里云,保存该图片 在阿里云的 路径 到 本地数据库
    微信所有国家列表
    YII load()
    ab命令压力测试
    fatal: Could not read from remote repository
    JS获取URL中参数值的4种方法
    yii 生成 模型
    php子类是否自动调用父类构造函数
    自己实现一个简化版的SpringMVC框架
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/9775274.html
Copyright © 2020-2023  润新知