bzoj 1997: [Hnoi2010]Planar

Description

Input

Output

Sample Input

2
6 9
1 4
1 5
1 6
2 4
2 5
2 6
3 4
3 5
3 6
1 4 2 5 3 6
5 5
1 2
2 3
3 4
4 5
5 1
1 2 3 4 5

Sample Output

NO
YES

HINT 

Source

Day1

 

考虑题目中给了一个哈密顿回路,那么我们把这个哈密顿回路在草稿纸上画成一个环。。。

然后考虑还不在环上的边,这些边有两种加入的方法,一是画在环的里面,二是画在环的外面。。。

对于两个冲突的边,那么他们两个人必须选择不同的画法才能不相交。。。

那么这个东西可以用二分图判定或者2-SAT来实现。。。interesting。。。

然而这个题有一个数组没memset调了半天。。。(注意m>3*n-6时要直接判掉。。。这是一个结论。。。)

// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=200050;
struct data{
  int x,y;
}e[N];
int T,n,m,rnk[N],c[N],bj[N];
int head[N],to[N],nxt[N],cnt,vis[N],flag,tmp,tmp2;
void lnk(int x,int y){
  to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
  to[++cnt]=x,nxt[cnt]=head[y],head[y]=cnt;
}
bool judge(int x1,int y1,int x2,int y2){
  if(x1>y1) swap(x1,y1);
  if(x2>y2) swap(x2,y2);
  if((x1<x2&&y1>x2&&y1<y2)||(x2<x1&&y2>x1&&y2<y1)) return 1;
  return 0;
}
void dfs(int x,int fa,int cor){
  vis[x]=cor;
  for(int i=head[x];i;i=nxt[i]){
    int y=to[i];
    if(y!=fa){
      if(vis[y]==-1) dfs(y,x,cor^1);
      else if(vis[y]!=(cor^1)) flag=1;
    }
  }
}
int main(){
  scanf("%d",&T);
  while(T--){
    scanf("%d%d",&n,&m);flag=0;
    memset(head,0,sizeof(head));cnt=0,tmp=0;tmp2=0;
    memset(vis,-1,sizeof(vis));
    memset(bj,0,sizeof(bj));
    for(int i=1;i<=m;i++) scanf("%d%d",&e[i].x,&e[i].y);
    for(int i=1;i<=n;i++) scanf("%d",&c[i]),rnk[c[i]]=i;
    if(m>3*n-6) {puts("NO");continue;}
    for(int i=1;i<=m;i++){
      int x=rnk[e[i].x],y=rnk[e[i].y];
      if(x>y) swap(x,y);
      if(y-x==1||(y==n&&x==1)) bj[i]=1,tmp2++;
    }
    for(int i=1;i<=m;i++){
      for(int j=i+1;j<=m;j++){
    if(judge(rnk[e[i].x],rnk[e[i].y],rnk[e[j].x],rnk[e[j].y])&&bj[i]==0&&bj[j]==0){
      lnk(i,j),tmp++;
    }
      }
    }
    for(int i=1;i<=m;i++) if(vis[i]==-1&&bj[i]==0) dfs(i,i,0);
    if(flag) puts("NO");
    else puts("YES");
  }
  return 0;
}
posted @ 2017-07-24 22:18  qt666  阅读(230)  评论(0编辑  收藏  举报