通过关系构图,然后进行跑2-SAT模板
附上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1005;
const int maxm=2000005;
const int inf=1000000000;
struct edge{
int v,next;
};
edge edges[maxm];
int head[maxn],e;
int n,m;
int dfn[maxn],low[maxn];
int index,instack[maxn];
int scc;
int top,st[maxn],fa[maxn];
int x[maxn],y[maxn];
void add_edges(int x,int y)
{
edges[e].v=y;
edges[e].next=head[x];
head[x]=e++;
}
void tarjan(int u)
{
int v;
instack[u]=1;
st[++top]=u;
dfn[u]=low[u]=++index;
for(int i=head[u];~i;i=edges[i].next){
int v=edges[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++;
do{
v=st[top--];
instack[v]=0;
fa[v]=scc;
}while(v!=u);
}
}
bool check()
{
for(int i=1;i<=m;i++){
if(fa[i]==fa[i+m]){
return false;
}
}
return true;
}
int main()
{
scanf("%d%d",&n,&m);
e=index=scc=top=0;
memset(dfn,0,sizeof(dfn));
memset(instack,0,sizeof(instack));
memset(head,-1,sizeof(head));
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])){
add_edges(i,j+m);
add_edges(j,i+m);
add_edges(i+m,j);
add_edges(j+m,i);
}
}
}
n=2*m;
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(i);
}
}
if(check()){
printf("panda is telling the truth...\n");
}else{
printf("the evil panda is lying again\n");
}
return 0;
}