1 条题解
-
0
自动搬运
来自洛谷,原作者为

cmd2001
rm -rf ~搬运于
2025-08-24 21:46:31,当前版本为作者最后更新于2017-11-01 20:33:07,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
其实不用2-sat的,直接并查集。
先用平面图定理 m<=3*n+6 把边数减小到O(n)级别。
然后设 集合 i+m 表示 不能与i共存的边 所在的集合。
枚举每一对不能共存的边,如果已经在同一个集合内,则无解。
否则交叉连边 fa[find(i)]=j+m , fa[find(j)]=i+m 。
如何判断两条边是否相交?先把所有边坐标转换为哈密顿回路中的顺序坐标,对于任意两条边i,j,如果有xi<xj<yi<yj,则相交。
注意如果两条边任意不在同一条边上的两端点相同则不可能相交。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=2e3+1e1; int x[maxn<<4],y[maxn<<4],vis[maxn<<4]; int id[maxn]; int fa[maxn<<5]; int T,n,m; inline int findfa(int x) { return fa[x] == x ? x : fa[x] = findfa(fa[x]); } inline void initfa() { for(int i=1;i<=m<<1;i++) fa[i] = i; } inline bool cross(int x1,int x2,int y1,int y2) { if( x1 == x2 || y1 == y2 || x1 == y2 || x2 == y1 ) return 0; if( x1 < x2 && y1 < y2 && x2 < y1 ) return 1; if( x2 < x1 && y2 < y1 && x1 < y2 ) return 1; return 0; } inline bool check() { initfa(); for(int i=1;i<=m;i++) { if( vis[i] ) continue; for(int j=1;j<=m;j++) { if( vis[j] ) continue; if( !cross(x[i],x[j],y[i],y[j]) ) continue; int fai = findfa(i) , faj = findfa(j); if( fai == faj ) return 0; fa[fai] = findfa( j + m ), fa[faj] = findfa( i + m ); } } return 1; } inline void init() { memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); memset(vis,0,sizeof(vis)); n = m = 0; } inline int getint() { int ret = 0; char ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( '0' <= ch && ch <= '9' ) ret = ret * 10 + ( ch - '0' ), ch = getchar(); return ret; } int main() { T = getint(); while( T-- ) { init(); n = getint() , m = getint(); for(int i=1;i<=m;i++) x[i] = getint() , y[i] = getint(); for(int i=1;i<=n;i++) id[getint()] = i; if( m > 3 * n + 6 ) { puts("NO"); continue; } for(int i=1,a,b;i<=m;i++) { a = id[x[i]] , b = id[y[i]]; x[i] = min( a , b ), y[i] = max( a , b ); } for(int i=1;i<=m;i++) if( y[i] == x[i] + 1 || ( y[i]==n && x[i]==0) ) vis[i] = 1; if( check() ) puts("YES"); else puts("NO"); } return 0; }
- 1
信息
- ID
- 2282
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者