poj3207 Ikki's Story IV - Panda's Trick 2-sat问题
题意:给定一个圈,m条边(给定),边可以通过外面连,也可以通过里面连,
问连完这m条边后,是否可以做到边两两不相交
题解:
将连里面和连外面分别当做一种决策(即每条边都是决策点),
如果有两条边相冲突,即如果这两条边都连里面就会导致不合法,那就
x --- > y' , y --- > x',
额。。。那怎么判断不合法?
注意到被边u ---> v(u < v)割成两半的分别是:
u ~ v,其他,
一条边不经过这条边的充要条件是:两个端点都在这条边的同一侧。
也就是要么都属于u ~ v,要么都属于其他。
x = x * 2,表示连里面
x = x ^ 1,表示连外面
连边的时候记得双向建边,不然是不可能有大于1的强联通分量的(因为对于任意x点只有出边,任意x'点只有入边)
找到一组冲突的就连x --- > y', y --- > x'.
表示x连里面,y就要放外面,反之同理
#include<fstream>//文件输入输出
using namespace std;
#define R register int
#define getchar() *o++
#define AC 2200
#define ac 4000100
char READ[],*o=READ;
int n, m, all, tt, cnt;
int low[AC], dfn[AC], belong[AC];
int date[ac], Next[ac], Head[AC], tot;
int s[AC], top;
bool z[AC];
struct node{
int x,y;
}way[AC]; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline void add(int f,int w)
{
date[++tot] = w, Next[tot] = Head[f], Head[f] = tot;
date[++tot] = f, Next[tot] = Head[w], Head[w] = tot;//反之也成立,所以要加双向边,不然是不可能有几个连一起的
// printf("%d ---> %d\n",f,w);
} inline void upmin(int &a,int b)
{
if(b < a) a = b;
} void pre()
{
n=read(), m=read(), all = n * ;
for(R i=;i<=m;i++)
{
way[i].x = read(), way[i].y = read();
if(way[i].x > way[i].y) swap(way[i].x, way[i].y);
for(R j=;j<i;j++)//防止重边
{
if(way[j].x > way[i].x && way[j].y < way[i].y) continue;
if(way[j].x < way[i].x && way[j].y < way[i].x) continue;
if(way[j].x > way[i].y && way[j].y > way[i].y) continue;
if(way[j].x < way[i].x && way[j].y > way[i].y) continue;//剩下的就都是冲突的
add(i * , (j * ) ^ );
add(j * , (i * ) ^ );
}
}
} void tarjan(int x)
{
int now;
dfn[x] = low[x] = ++tt;
s[++top] = x, z[x] = true;
for(R i = Head[x]; i ; i = Next[i])
{
now = date[i];
if(!dfn[now])
{
tarjan(now);
upmin(low[x], low[now]);
}
else if(z[now])
upmin(low[x], low[now]);
}
int b = ++cnt;
if(dfn[x] == low[x])
{
while(now = s[top--])
{
belong[now] = b;
z[now] = false;
if(now == x) break;
}
}
} void work()
{
for(R i = ; i <= all; i += )
{
if(belong[i] == belong[i ^ ])
{
printf("the evil panda is lying again\n");
return ;
}
}
printf("panda is telling the truth...\n");
} int main()
{
freopen("in.in","r",stdin);
fread(READ, , , stdin);
pre();
for(R i=;i<=all;i++)
if(!dfn[i]) tarjan(i);
work();
fclose(stdin);
return ;
}
poj3207 Ikki's Story IV - Panda's Trick 2-sat问题的更多相关文章
- POJ3207 Ikki's Story IV – Panda's Trick
Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 9426 Accepted: 3465 Description liym ...
- POJ3207 Ikki's Story IV - Panda's Trick 【2-sat】
题目 liympanda, one of Ikki's friend, likes playing games with Ikki. Today after minesweeping with Ikk ...
- poj3207 Ikki’s Story IV – Panda’s Trick
2-SAT. tarjan缩点.强连通分量的点要选一起选. #include<cstdio> #include<algorithm> #include<cstring&g ...
- POJ-3207 Ikki's Story IV - Panda's Trick 2sat
题目链接:http://poj.org/problem?id=3207 题意:在一个圆圈上有n个点,现在用线把点两两连接起来,线只能在圈外或者圈内,现给出m个限制,第 i 个点和第 j 个点必须链接在 ...
- poj3207 Ikki's Story IV - Panda's Trick 2-SAT
题目传送门 题意:在一个圆上顺时针安放着n个点,给出m条线段连接端点,要求线段不相交,线段可以在圆内也可以在圆外,问是否可以. 思路:假设一条线段,放在圆外是A,放在园内是A',那么两条线段如果必须一 ...
- 【POJ3207】Ikki's Story IV - Panda's Trick
POJ 3207 Ikki's Story IV - Panda's Trick liympanda, one of Ikki's friend, likes playing games with I ...
- POJ 3207 Ikki's Story IV - Panda's Trick(2-sat问题)
POJ 3207 Ikki's Story IV - Panda's Trick(2-sat问题) Description liympanda, one of Ikki's friend, likes ...
- POJ 3207 Ikki's Story IV - Panda's Trick
Ikki's Story IV - Panda's Trick Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 7296 ...
- poj 3207 Ikki's Story IV - Panda's Trick (2-SAT)
http://poj.org/problem?id=3207 Ikki's Story IV - Panda's Trick Time Limit: 1000MS Memory Limit: 13 ...
随机推荐
- Python常用函数--文档字符串DocStrings
Python 有一个甚是优美的功能称作python文档字符串(Documentation Strings),在称呼它时通常会使用另一个短一些的名字docstrings.DocStrings 是一款你应 ...
- CodeForces - 913C(二进制)
链接:CodeForces - 913C 题意:给出 n 瓶饮料的花费 C 数组,每瓶的体积是 2^(i-1) 升,求至少买 L 升的最少花费. 题解:二进制数的组合可以表示任何一个数.第 i 的饮料 ...
- 【Linux 运维】linux系统查看版本信息
查看linux系统版本信息: [root@kvm-host~]# cat /proc/version (Linux查看当前操作系统版本信息)Linux version 3.10.0-514 ...
- python—IDLE的shell上下翻看历史
Alt+p和Alt+n,分别向上(history previous)和向下(history next)调出使用过的历史命令.
- 利用人脸特征提取DeepID--解读世纪晟人脸识别
概述:DeepID的目标是人脸验证(判断两张图片是否是一个人),同时衍生出人脸识别(多次人脸验证). DeepID采用增大数据集的方法: 增加新的数据,celebFaces(87628张图片,5436 ...
- iostat lsof
转至:http://www.51testing.com/html/48/202848-242043.html 命令总结: 1. top/vmstat 发现 wa%过高,vmstat b >1: ...
- C++标准库算法
一.只读算法 1. find() 2. count() 3. accumulate 4. equal 二.写入算法 1. fill 2. fill_n 3. copy 4. replace 5. re ...
- 2017秋软工1 - 本周PSP
1.本周PSP 2. 本周PSP饼状图 3. 本周进度条 4. 累计进度图
- 20172333 2017-2018-2 《Java程序设计》第7周学习总结
20172333 2017-2018-2 <Java程序设计>第7周学习总结 教材学习内容 1.继承是创建新类的快捷方式之一,继承可以使用父类的所有方法及对象. 2.继承具有单向性,父类不 ...
- gcc 学习笔记(一) - 编译C程序 及 编译过程
一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...