bzoj 1997 Planar [并查集] [二分图判定] [2-SAT]
来源:互联网 发布:南京麦芽金服数据 编辑:程序博客网 时间:2024/06/04 19:03
1997: [Hnoi2010]Planar
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 1509 Solved: 585
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
Source
Day1
三种做法,并查集,二分图判定,2-SAT
前两种就是上一道题的check,但是注意要剪枝,m<=3n-6时才有可能成为平面图。
2-SAT解法:
这道题把所有边拆成两个,分别代表在里面和在外面,然后又里面和外面取且一定取一个,那么连上四条边即可。。
又因为这道题只用判断可行性,那么就只用缩点之后判断是否有冲突即可,如果要输出方案,那么就需要按照拓扑序的反序进行点的确定,然后依次标记可选的点,传递不能选的标记,然后该图的染色就是2-SAT问题的解。
另外要注意提前break的时候要保证读完该组数据,不然RE…
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std;#define smax(x,tmp) x=max((x),(tmp))#define smin(x,tmp) x=min((x),(tmp))#define maxx(x1,x2,x3) max(max(x1,x2),x3)#define minn(x1,x2,x3) min(min(x1,x2),x3)const int INF=0x3f3f3f3f;const int maxnode = 205;const int maxn = 605;const int maxm = 10005;struct Edge{ int to,next;}edge[maxn*maxn<<2]; // 4 edges per conditionint head[maxn<<1]; // dividedint maxedge;inline void addedge(int u,int v){ edge[++maxedge] = (Edge) { v,head[u] }; head[u] = maxedge;}struct Road{ int u,v;}road[maxn],save[maxm];bool g[maxnode][maxnode];int a[maxnode],order[maxnode];int n,m,tmp;void init(){ memset(g,0,sizeof(g)); memset(head,-1,sizeof(head)); maxedge = -1; m=0; for(int i=1;i<=tmp;i++) scanf("%d%d",&save[i].u,&save[i].v); for(int i=1;i<=n;i++) scanf("%d",a+i),order[a[i]]=i; if(tmp>n*3-6) return; // spacial judge after scanning!! for(int i=1;i<n;i++) g[a[i]][a[i+1]] = g[a[i+1]][a[i]] = true; g[a[1]][a[n]] = g[a[n]][a[1]] = true; for(int i=1;i<=tmp;i++) if(!g[save[i].u][save[i].v]) road[++m]=save[i];}inline bool cross(int i,int j) // cases of including node n,1 is considered another way{ int x1=order[road[i].u],y1=order[road[i].v]; int x2=order[road[j].u],y2=order[road[j].v]; if(x1>y1) swap(x1,y1); if(x2>y2) swap(x2,y2); return (x1<x2 && x2<y1 && y1<y2) || (x2<x1 && x1<y2 && y2<y1);}int dfn[maxn<<1],sccno[maxn<<1];bool insta[maxn<<1];int scc_cnt,dfs_clock;stack <int> sta;int dfs(int u){ int lowu=dfn[u]=++dfs_clock; sta.push(u); insta[u]=true; for(int i=head[u];~i;i=edge[i].next) { int v = edge[i].to; if(!dfn[v]) { int lowv = dfs(v); smin(lowu,lowv); } else if(insta[v]) smin(lowu,dfn[v]); } if(lowu>=dfn[u]) { scc_cnt++; int t; do { t=sta.top(); sta.pop(); insta[t]=false; sccno[t]=scc_cnt; // if needed to print , note the nodes of SCC }while(t^u); } return lowu;}void Tarjan(){ memset(dfn,0,sizeof(dfn)); memset(sccno,0,sizeof(sccno)); dfs_clock = scc_cnt = 0; for(int i=1;i<=m;i++) { if(!dfn[i]) dfs(i); if(!dfn[i+m]) dfs(i+m); }}inline bool check(){ for(int i=1;i<=m;i++) if(sccno[i] == sccno[i+m]) return false; return true;}int main(){ #ifndef ONLINE_JUDGE freopen("planar.in","r",stdin); freopen("planar.out","w",stdout); #endif int cas; scanf("%d",&cas); while(cas--) { scanf("%d%d",&n,&tmp); init(); if(tmp>n*3-6) // judge after scanning all data!! { printf("NO\n"); continue; } for(int i=1;i<m;i++) for(int j=i+1;j<=m;j++) if(cross(i,j)) { addedge(i,j+m); addedge(j,i+m); addedge(i+m,j); addedge(j+m,i); } Tarjan(); if(check()) printf("YES\n"); else printf("NO\n"); } return 0;}
0 0
- bzoj 1997 Planar [并查集] [二分图判定] [2-SAT]
- BZOJ 1997: [Hnoi2010]Planar|2-SAT|二分图染色
- BZOJ 1997 HNOI 2010 Planar 2-SAT
- BZOJ 1997 Hnoi2010 Planar 2-sat
- BZOJ 1997 HNOI 2010 Planar 2-SAT
- bzoj 1997: [Hnoi2010]Planar (2-SAT)
- BZOJ 1997: [Hnoi2010]Planar 2-sat
- bzoj 1997: [Hnoi2010]Planar 2-SAT+平面图
- 【BZOJ1997】[Hnoi2010]Planar【平面图判定】【2-SAT】
- BZOJ 1997: [Hnoi2010]Planar 平面图判定,TWOSAT
- 1997: [Hnoi2010]Planar 2-SAT
- 【BZOJ4078】[Wf2014]Metal Processing Plant【2-SAT】【二分】【二分图】【并查集】
- 【平面图判定+2-SAT验证】BZOJ1997 [Hnoi2010]Planar
- [BZOJ1997][Hnoi2010]Planar && 并查集
- BZOJ1997: [Hnoi2010]Planar(并查集)
- BZOJ 4025 二分图 分治+并查集
- BZOJ-1854 游戏 二分图匹配 (并查集)
- BZOJ 4025|二分图|CDQ分治|并查集|LCT
- 对于application一点理解
- C++面试宝典2011
- HDU5794 A Simple Chess
- php组词算法
- 2016多校联赛7H (hdu5828) Rikka with Sequence
- bzoj 1997 Planar [并查集] [二分图判定] [2-SAT]
- nodejs之底层运作模式
- AngularJS入门笔记(1)
- C++中的RAII机制
- extern 关键字用法
- Mac OS 使用技巧汇总
- Java Web 初级程序员 -第6天学习内容:接口和抽象类
- SpringMVC响应Ajax请求(@Responsebody注解返回页面)
- Android模拟器访问本地IIS冲突问题处理方法