• 【图论/平面图】AcWing 403. 平面


    平面图

    首先介绍一下平面图的相关性质:

    若图 \(G\) 能被画在平面上且不同的边仅在端点处相交,则称图 \(G\)平面图。画出的没有边相交的图称为 \(G\) 的平面表示或平面嵌入

    一个图的平面嵌入会将整个平面划分成若干个互不连通的区域,每个区域称为一个

    其中,无界的区域称作外部面,反之称为内部面。包围某个面的所有边构成了该面的边界

    通过球极投影可以发现内部面外部面本质一样。

    欧拉公式

    对于一个连通的平面嵌入 \(G\),它的点数 \(V\) ,边数 \(E\),面数 \(F\) 满足:

    \[V - E + F = 2 \]

    推广可得 \(C\) 个连通块满足:

    \[V − E + F = C + 1 \]

    通过欧拉公式,我们可以得到:

    对于一个简单的连通的平面嵌入 \(G\),若 \(V ≥ 3\),则满足 \(E ≤ 3V − 6\)

    证明:

    \(G\) 中每个面的边界上至少有三条边,同时,每条边与两个面相邻,因此满足关系:\(2E\geq 3F\)

    代入欧拉公式即证毕。

    本题分析

    我们挖掘一下两条边之间约束关系:

    记哈密顿路径的顺序(时间戳)为 \(dfn\)\(a, b\) 为一条边两个点的时间戳,\(c,d\) 为另一条边两个点的时间戳,不妨设 \(a<c\),那么画在数轴上就是:

                 -------------
                 |           |
           ------------      |
           ↓     ↓     ↓     ↓
    -------a-----c-----b-----d-------
    

    \(c\in(a, b) ~ \cap ~ b\in (c, d)\) 上时两条边必须分居哈密顿环的内侧、外侧。

    这个关系正好可以使用并查集来刻画。

    题目有 \(2-SAT\) 的标签,但事实上不需要使用缩点,因为这个约束关系可以看作是无向图的边,用并查集维护即可。

    注意到本题的边的范围很大,但是根据平面图的性质我们可以先筛掉 \(E > 3V − 6\) 的情况,这样边的数量就足够支持 \(O(n^2)\) 的枚举了。

    实现

    // Problem: 平面
    // Contest: AcWing
    // URL: https://www.acwing.com/problem/content/405/
    // Memory Limit: 64 MB
    // Time Limit: 1000 ms
    // 
    // Powered by CP Editor (https://cpeditor.org)
    
    #include<bits/stdc++.h>
    using namespace std;
     
    #define debug(x) cerr << #x << ": " << (x) << endl
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    #define pb push_back
    #define all(x) (x).begin(), (x).end()
     
    #define x first
    #define y second
    using pii = pair<int, int>;
    using ll = long long;
     
    inline void read(int &x){
        int s=0; x=1;
        char ch=getchar();
        while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    const int N=6006;
    
    int n, m;
    pii e[N];
    int dfn[N];
    
    int f[N<<1];
    
    int find(int x){
    	return x==f[x]? x: f[x]=find(f[x]);
    }
    
    signed main(){
    	int cs; cin>>cs;
    	while(cs--){
    		cin>>n>>m;
    		int cntm=0;
    		rep(i,1,m) read(e[i].x), read(e[i].y), cntm+=(e[i].x!=e[i].y);
    		rep(i,1,n){
    			int u; read(u);
    			dfn[u]=i;
    		}
    		
    		if(n>=3 && cntm>3*n-6){
    			puts("NO");
    			continue;
    		}
    		
    		rep(i,1,m<<1) f[i]=i;
    		rep(i,1,m) rep(j,i+1,m){
    			auto [a, b]=e[i];
    			auto [c, d]=e[j];
    			if(a==b || c==d) continue;
    			a=dfn[a], b=dfn[b], c=dfn[c], d=dfn[d];
    			if(a>b) swap(a, b);
    			if(c>d) swap(c, d);
    			if(a>c) swap(a, c), swap(b, d);
    		
    			if(b>c && b<d && c>a && c<b){
    				f[find(i+m)]=find(j);
    				f[find(j+m)]=find(i);
    			}
    		}
    		
    		bool ok=true;
    		rep(i,1,m) ok&=(find(i)!=find(i+m));
    		puts(ok? "YES": "NO");
    	}	
    	return 0;
    }
    
  • 相关阅读:
    python项目打包成exe
    sql同比环比计算
    七款好看文字样式纯css
    一站式智能芯片定制技术
    实战清除电脑上恶意弹出广告窗口
    GAAFET与FinFET架构
    MIPI多媒体接口
    Intel GPU实现游戏与数据中心
    芯片倒爷赚钱术
    Cache Memory技术示例
  • 原文地址:https://www.cnblogs.com/Tenshi/p/16466551.html
Copyright © 2020-2023  润新知