2-SAT poj3207将边看做点

Ikki‘s Story IV - Panda‘s Trick

Time Limit: 1000MS   Memory Limit: 131072K
Total Submissions: 10238   Accepted: 3762

Description

liympanda, one of Ikki’s friend, likes playing games with Ikki. Today after minesweeping with Ikki and winning so many times, he is tired of such easy games and wants to play another game with Ikki.

liympanda has a magic circle and he puts it on a plane, there are n points on its boundary in circular border: 0, 1, 2, …, n ? 1. Evil panda claims that he is connecting m pairs of points. To connect two points, liympanda either places the link entirely inside the circle or entirely outside the circle. Now liympanda tells Ikki no two links touch inside/outside the circle, except on the boundary. He wants Ikki to figure out whether this is possible…

Despaired at the minesweeping game just played, Ikki is totally at a loss, so he decides to write a program to help him.

Input

The input contains exactly one test case.

In the test case there will be a line consisting of of two integers: n and m (n ≤ 1,000, m ≤ 500). The following m lines each contain two integers ai and bi, which denote the endpoints of the ith wire. Every point will have at most one link.

Output

Output a line, either “panda is telling the truth...” or “the evil panda is lying again”.

Sample Input

4 2
0 1
3 2

Sample Output

panda is telling the truth...

将边看成点,然后拆点,一个代表圆内边(以点代边),一个代表园外边.由约束条件搞出哪些点在所建图中必定要相连,然后跑tajan得到联通块‘并查集也是可以的
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1005;
const int M=2000005;
const int INF=1000000000;
int n,m,tot,head[N];
int dfn[N],low[N],index,instack[N],scc;
int top,st[N],fa[N];
int x[N],y[N];
struct edge{
   int v,nxt;
}e[M];
void init(){
   tot=index=scc=top=0;
   memset(dfn,0,sizeof(dfn));
   memset(instack,0,sizeof(instack));
   memset(head,-1,sizeof(head));
}
void insert(int x,int y){
   e[tot].v=y;
   e[tot].nxt=head[x];
   head[x]=tot++;
}
void Tarjan(int u){
   instack[u]=1;
   st[top++]=u;
   dfn[u]=low[u]=++index;
   for(int i=head[u];~i;i=e[i].nxt){
    int v=e[i].v;
    if(!dfn[v]) {
        Tarjan(v);
        low[u]=min(low[u],low[v]);
    }
    else if(instack[v]) low[u]=min(low[u],dfn[v]);
   }
   if(dfn[u]==low[u]){
    ++scc;int t;
    do{
        t=st[--top];
        instack[t]=0;
        fa[t]=scc;
    }while(t!=u);
   }
}
void build(){
   for(int i=1;i<=m;++i){
    scanf("%d%d",&x[i],&y[i]);
    ++x[i],++y[i];
    if(x[i]>y[i]) swap(x[i],y[i]);
   }
   for(int i=1;i<=m;++i) for(int j=i+1;j<=m;++j)
   if((x[i]<=x[j]&&y[i]>=x[j]&&y[i]<=y[j])||(x[i]>=x[j]&&x[i]<=y[j]&&y[i]>=y[j])){
    insert(i,j+m);
    insert(j,i+m);
    insert(i+m,j);
    insert(j+m,i);
   }
   n=2*m;
}
bool check(){
   for(int i=1;i<=m;++i) if(fa[i]==fa[i+m]) return false;
   return true;
}
void solve(){
   for(int i=1;i<=n;++i) if(!dfn[i]) Tarjan(i);
   if(check()) puts("panda is telling the truth...");
   else puts("the evil panda is lying again");
}
int main(){
    scanf("%d%d",&n,&m);
    init();
    build();
    solve();
}
时间: 2024-10-11 04:27:14

2-SAT poj3207将边看做点的相关文章

POJ 3207 Ikki&#39;s Story IV - Panda&#39;s Trick(2 - sat啊)

题目链接:http://poj.org/problem?id=3207 Description liympanda, one of Ikki's friend, likes playing games with Ikki. Today after minesweeping with Ikki and winning so many times, he is tired of such easy games and wants to play another game with Ikki. liy

LA 3211 飞机调度(2—SAT)

https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间为E,晚着陆时间为L,不得在其他时间着陆.你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全.换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最小值. 思路: 二分查找最大值P,每次都用2—SAT判断是否可行. 1 #include<iostream>

hdu1695 GCD 莫比乌斯反演做法+枚举除法的取值 (5,7),(7,5)看做同一对

/** 题目:hdu1695 GCD 链接:http://acm.hdu.edu.cn/status.php 题意:对于给出的 n 个询问,每次求有多少个数对 (x,y) , 满足 a ≤ x ≤ b , c ≤ y ≤ d ,且 gcd(x,y) = k ,(5,7),(7,5)看做同一对, gcd(x,y) 函数为 x 和 y 的最大公约数. 本题默认:a = c = 1; 0 < a <= b <= 100,000, 0 < c <= d <= 100,000,

poj3207 Ikki&#39;s Story IV - Panda&#39;s Trick

Description liympanda, one of Ikki’s friend, likes playing games with Ikki. Today after minesweeping with Ikki and winning so many times, he is tired of such easy games and wants to play another game with Ikki. liympanda has a magic circle and he put

8.3吝啬SAT问题

吝啬SAT问题是这样的:给定一组子句(每个子句都是其中文字的析取)和整数k,求一个最多有k个变量为true的满足赋值--如果该赋值存在.证明吝啬SAT是NP-完全问题. 1.易知吝啬SAT的解可以在多项式时间内验证,因此属于NP问题. 2.如果我们把吝啬SAT问题中的k设置为输入的数目,那么SAT问题就可以规约到吝啬SAT问题,所以吝啬SAT问题是np-完全问题.

多边形碰撞 -- SAT方法

检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形是分离的,否则找下一条向量来继续投影.我们不需要比较很多条向量,因为已经在数学上证明,多边形每条边的垂直向量就是我们需要的向量. 1.AABB 让我们首先以AABB开始(AABB是一种两边分别平行于X-Y轴的矩形) 判断两个AABB是否碰撞,我们只需要投影两次,分别是投影在平行于X轴和Y轴的向量上

poj3207:Ikki&#39;s Story IV-Panda&#39;s Trick【2-sat tarjan】

题目大意:圆盘上顺次安放0, 1, 2, …, n – 1的点,每次给出两个点需要连边,可以选择在圆盘的正面连边或在圆盘的反面连边,问是否存在一种方案使得所有连线不相交? 思路:本问题可以等价成:圆盘上原本有N条线,每条线在正反面都有画上,将在正反面的两条线只保留一根,问是否存在一种方案使得所有连线不相交? 这样问题就成了赤果果的2-SAT问题了,注意到两条线如果都在正面会相交,那么都在反面也会相交,因此构图时应是无向图,按照2-SAT的形式构完图后,用TARJAN求缩点,由于在一个SCC中的点

hdu 4751 Divide Groups 2—sat问题 还是未理解

Divide Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1443    Accepted Submission(s): 512 Problem Description This year is the 60th anniversary of NJUST, and to make the celebration mor

POJ3207 Ikki&#39;s Story IV – Panda&#39;s Trick

Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 9426   Accepted: 3465 Description liympanda, one of Ikki’s friend, likes playing games with Ikki. Today after minesweeping with Ikki and winning so many times, he is tired of such easy gam