本文主要是介绍[POJ3207]Ikki's Story IV - Panda's Trick,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
poj3207-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.
输入
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 a line, either “panda is telling the truth…” or “the evil panda is lying again”.
样例输入
4 2
0 1
3 2
样例输出
panda is telling the truth…
SOL
2-SAT模板。
题面的大致意思是:在一个圆上有n个点,m条边,边可以在圆外或圆内,边与边之间不能相交,求是否有合法解。
对于这道题,相交只有一种情况:
那么有2种方法可以使其不相交:
于是考虑将每条边转换成两个点,表示圆外边和圆内边,于是就可以转换成2-SAT问题
效率是 O ( M 2 ) O(M^2) O(M2)的(即枚举连边的复杂度)
代码:
#include<stack>
#include<cstdio>
#include<iostream>
#define N 1005
#define M 505
#define T 1000005
#define re register
#define ll long long
using namespace std;
inline int rd(){int data=0;static char ch=0;ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))data=(data<<1)+(data<<3)+ch-'0',ch=getchar();return data;
}
int n,m,scc,tim,col[N],low[N],dfn[N];bool vis[N];
stack<int>s;
struct edge{int u,v;}E[M];
struct node{int v,nxt;}e[T];int cnt,first[N];
inline void add(int u,int v){e[++cnt].v=v;e[cnt].nxt=first[u];first[u]=cnt;}
void dfs(int u){low[u]=dfn[u]=++tim;s.push(u);vis[u]=1;for(int re i=first[u];i;i=e[i].nxt){int re v=e[i].v;if(!dfn[v]){dfs(v);low[u]=min(low[u],low[v]);}else if(vis[v])low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]){++scc;while(1){int re t=s.top();s.pop();col[t]=scc;vis[t]=0;if(t==u)break;}}
}
inline bool check(int a,int b){if(E[a].v<=E[b].u||E[a].u>=E[b].v)return true;if(E[a].u<=E[b].u&&E[a].v>=E[b].v)return true;if(E[b].u<=E[a].u&&E[b].v>=E[a].v)return true; return false;
}
inline void con(int u,int v){add(u,v),add(v,u);}
inline void link(int u,int v){con(u<<1,v<<1|1),con(v<<1,u<<1|1);}
int main(){n=rd();m=rd();for(int re i=0;i<m;i++){int re x=rd(),y=rd();if(x>y)swap(x,y);E[i].u=x,E[i].v=y;}for(int re i=0;i<m;i++)for(int re j=0;j<i;j++)if(!check(i,j))link(i,j);for(int re i=0;i<m*2;i++)if(!dfn[i])dfs(i);for(int re i=0;i<m;i++){if(col[i<<1]==col[i<<1|1]){cout<<"the evil panda is lying again";return 0;};}cout<<"panda is telling the truth...";return 0;
}
这篇关于[POJ3207]Ikki's Story IV - Panda's Trick的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!