【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 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...
题目大意
在一个圆上有n个点(依从从0~n-1编号)。再给定m组点,表示这两个点要相互连接,连接的方式要么在圈外,要么在圈内。询问,能否使得任意两个连线都没有交点(端点除外)?
解决
如果存在交点,是什么情况?
在圆内如果有交点,例如,(0,1)(2,4)的两条连线。在图上很显然的就存在交点。观察一下,那么就是两组连线的点依次出现。
即:Link[i].a < Link[j].a < Link[i].b < Link[j].b(a始终比b小)
那么此时一定存在交点
再来看在圆外的情况
原谅我图画得奇丑无比(然而我已经尽力了)
我们可以发现,如果在圆外存在交点,那么在园内必定存在交点。
所以,式子和上面一模一样。
知道了这个边是怎么回事。题目就转换为了:对于任意两组边,如果存在相交的关系,那么他们不能够同时存在于一侧(只能一内一外)。
那么它就转换为了一个2-sat问题,每条边要么在内,要么在外。
如果2-sat问题不熟可以做一下【POI2001和平委员会】理解一下
(http://blog.csdn.net/qq_30974369/article/details/73927421)
接下来不难了,因为只需要判断可行性,所以这类2-sat就非常容易解决,连完了边,用Tarjan缩点(因为在一个强连通分量中的点要么都选,要么都不选),依次判断即可。(具体实现看看代码)
补充一下一般2-sat问题的做法:
1.根据题目含义建边
2.使用Tarjan进行缩点
3.检查每一组是否存在矛盾(某个点的选择A和选择B在同一个相连通分量里面)
4.对缩出来的点进行拓扑排序,依次染色即可(一定存在解)
如果不能够理解为什么存在解,就到打开上面的链接,那个Blog里面贴了一个大佬的2-sat详解
这道题目做完了可以接着做下一道【POJ3683】
http://blog.csdn.net/qq_30974369/article/details/74025251
/*
POJ 3207 Ikki's Story IV - Panda's Trick
题目大意:
n个点连成一圈,指定m对点之间要有连线
可以连在圈外也可以连在圈内
问能否使所有的连线不相交
思路:
这题的点只是一个媒介
对于每一条边而言,有两种选择:在圈内/在圈外
因此是一道比较显然的2-sat问题
易证明:若两条边在圈内相交则必定在圈外相交
那么,只要通过点的位置来考虑边是否相交
用2-sat即可求解
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAX=100000;
struct Node
{
int v,next;
}e[MAX];
int h[MAX],cnt=0;
int n,m,dfn[MAX],low[MAX],tim=0;
int Linkx[MAX],Linky[MAX];
int S[MAX],top=0;
int G[MAX],group=0;
bool vis[MAX];
inline void Add(int u,int v)
{
e[cnt]=(Node){v,h[u]};
h[u]=cnt++;
}
inline void Link();//连边
inline void Tarjan(int u);//缩点
int main()
{
memset(h,-1,sizeof(h));
cin>>n>>m;
for(int i=1;i<=m;++i)
{
cin>>Linkx[i]>>Linky[i];//储存每条边的两个端点
Linkx[i]++;Linky[i]++;//因为是从0开始的,都加1
if(Linkx[i]>Linky[i])
swap(Linkx[i],Linky[i]);//x中存编号较小的点
}
Link(); //连边
for(int i=1;i<=2*m;++i)//缩点
if(!dfn[i])Tarjan(i);
for(int i=1;i<=m;i++)
{
if(G[i]==G[i+m])
{
cout<<"the evil panda is lying again"<<endl;
return 0;
}
}
cout<<"panda is telling the truth..."<<endl;
return 0;
}
void Link()//通过点的关系把所有的边的关系找出,转化为2-sat
{
for(int i=1;i<=m;++i)
for(int j=i+1;j<=m;++j)
{
if(((Linkx[i]<=Linkx[j])&&(Linkx[j]<=Linky[i])&&(Linky[i]<=Linky[j]))
||((Linkx[i]>=Linkx[j])&&(Linkx[i]<=Linky[j])&&(Linky[j]<=Linky[i])))
{
//出现交叉情况不能够同时选择
Add(i,j+m);//i内j外
Add(j,i+m);//反向边
Add(i+m,j);//i外j内
Add(j+m,i);//反向边
// i 表示第i条边连在内侧
// i+m 表示第i条边连在外侧
}
}
}
void Tarjan(int u)//缩点
{
dfn[u]=low[u]=++tim;
S[++top]=u;
vis[u]=true;
int v;
for(int i=h[u];i!=-1;i=e[i].next)
{
v=e[i].v;
if(!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else
if(vis[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
++group;
do
{
v=S[top--];
vis[v]=false;
G[v]=group;
}while(v!=u&&top);
}
}
/*
写在AC后面:
这题我WA了很久,并不知道自己哪里错了
只到最后,忽然,发现,自己,
在,连边的,时候,尽然,没有,加{},把Add()打包。
我,真是,智障,了。。。
*/
【POJ3207】Ikki's Story IV - Panda's Trick的更多相关文章
- 【poj3207】Ikki's Story IV - Panda's Trick(2-sat)
传送门 题意: 给出一个圆,圆上有\(n\)个点,依次为\(0,1,\cdots,n-1\). 现在要连接\(m\)对点,每次连接时可以直接从里面连,也可以从外面连. 最后问,连完这\(m\)对点后, ...
- 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 ...
- 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)
Ikki's Story IV - Panda's Trick Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 6691 ...
- 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 ...
- 【POJ】3207 Ikki's Story IV - Panda's Trick
http://poj.org/problem?id=3207 题意:一个圆上顺时针依次排列着标号为1-n的点,这些点之间共有m条边相连,每两个点只能在圆内或者圆外连边.问是否存在这些边不相交的方案.( ...
- poj 3207 Ikki's Story IV - Panda's Trick【2-SAT+tarjan】
注意到相交的点对一定要一里一外,这样就变成了2-SAT模型 然后我建边的时候石乐志,实际上不需要考虑这个点对的边是正着连还是反着连,因为不管怎么连,能相交的总会相交,所以直接判相交即可 然后tarja ...
- POJ3207 Ikki's Story IV – Panda's Trick
Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 9426 Accepted: 3465 Description liym ...
随机推荐
- 整理的linux面试运维题
如何在非交互模式下把 /home/example/下所有.conf文件中的 192.168.0.2 改成 db01 ? find /home/example/ -type f -name &quo ...
- 织梦搜索页使用arclist标签
织梦默认不能在搜索页使用arclist标签,我们对代码做一些小改动即可 打开include/arc.searchview.class.php 一.查找代码: require_once(DEDEINC. ...
- 用Git的hooks实现项目的自动部署
https://segmentfault.com/a/1190000003836345?_ea=386770 http://blog.csdn.net/wsyw126/article/details/ ...
- FFMpeg在Ubuntu上的安装和使用
在Ubuntu Server上编译FFmpeg FFmpeg是最流行的开源视频转码工具包,在Ubuntu上可以直接通过apt-get安装,但是默认的编码器不提供x264这些non-free的编码器,所 ...
- Android动态加载技术(插件化技术)
No1: 插件化技术的好处: 1)减轻应用的内存和CPU占用 2)实现热插拔,即在不发布新版本的情况下更新某些模块 No2: 插件化方案必须要解决三个基础性问题:资源访问.Activity生命周期的管 ...
- hihoCoder 1036 Trie图 AC自动机
题意:给定n个模式串和一个文本串,判断文本中是否存在模式串. 思路:套模板即可. AC代码 #include <cstdio> #include <cmath> #includ ...
- ACdream1032 Component 树形DP
思路:dp[i][j]表示以i为根结点有j个连通节点的最小和, 当进行状态转移时需要利用01背包,节点u下面有多个子节点,每个子节点可以最多可以贡献cnt[v]个节点,cnt[v]表示以v为根结点的树 ...
- nyoj940 A dp problem 打表
首先枚举i,那么构成i^2的最小值为1个正方形,当然1~1000并不会都得到答案,那么剩下的数字就递增枚举这些数,这个数可能右多对数构成,则枚举这些数.例如 5 = 1 + 4, 5 = 2 + 3, ...
- 情景linux--如何优雅地退出telnet
情景linux--在脚本中如何优雅地退出telnet 情景 telnet命令是TELNET协议的用户接口,它支持两种模式:命令模式和会话模式.虽然telnet支持许多命令,但大部分情况下,我们只是使用 ...
- nginx笔记5-双机热备原理
1动静分离演示: 将笔记3的Demo改造一下,如图所示: 改造完成后,其实就是在网页上显示一张图片 现在启动Tomcat运行起来,如图: 可以看到图片的请求是请求Tomcat下的图片. 现在,通过把静 ...