【题目大意】
给出一张存在哈密顿回路的无向图,判断是否是平面图。
【思路】
首先平面图的一个性质:边数<=点数*3-6
因为存在哈密顿回路,可以将回路看作是一个圆,考量不再哈密顿回路中的边。如果两天边相交(判断相交可以随意yy一下),那么必然一条在圆内一条在圆外,显然是2-SAT。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<stack> 7 using namespace std; 8 const int MAXN=20000+50; 9 int n,m; 10 int u[MAXN],v[MAXN],pos[MAXN]; 11 vector<int> E[MAXN]; 12 int dfn[MAXN],low[MAXN],instack[MAXN],col[MAXN],cnt,colcnt; 13 stack<int> S; 14 15 int cross(int i,int j) 16 { 17 int x1=pos[u[i]],y1=pos[v[i]],x2=pos[u[j]],y2=pos[v[j]]; 18 if ((x1<x2 && x2<y1 && y1<y2) || (x2<x1 && x1<y2 && y2<y1)) return 1;else return 0; 19 } 20 21 void addedge(int u,int v) 22 { 23 E[u].push_back(v); 24 E[v].push_back(u); 25 } 26 27 28 void tarjan(int u) 29 { 30 dfn[u]=low[u]=++cnt; 31 S.push(u); 32 instack[u]=1; 33 34 for (int i=0;i<E[u].size();i++) 35 { 36 int son=E[u][i]; 37 if (!instack[son]) 38 { 39 tarjan(son); 40 low[u]=min(low[son],low[u]); 41 } 42 else 43 if (instack[son]==1) 44 low[u]=min(dfn[son],low[u]); 45 } 46 47 if (dfn[u]==low[u]) 48 { 49 colcnt++; 50 int x; 51 do 52 { 53 x=S.top(); 54 S.pop(); 55 col[x]=colcnt; 56 instack[x]=2; 57 }while (x!=u); 58 } 59 } 60 61 62 void init() 63 { 64 scanf("%d%d",&n,&m); 65 cnt=0,colcnt=0; 66 for (int i=0;i<MAXN;i++) vector<int>().swap(E[i]);//注意不要忘记清空 67 memset(instack,0,sizeof(instack)); 68 for (int i=1;i<=m;i++) 69 scanf("%d%d",&u[i],&v[i]); 70 for (int i=1;i<=n;i++) 71 { 72 int x; 73 scanf("%d",&x); 74 pos[x]=i; 75 } 76 } 77 78 void build() 79 { 80 for (int i=1;i<=m;i++) 81 if (pos[u[i]]>pos[v[i]]) swap(u[i],v[i]); 82 for (int i=1;i<=m;i++) 83 for (int j=i+1;j<=m;j++) 84 if (cross(i,j)) 85 { 86 addedge(i,j+m); 87 addedge(i+m,j); 88 } 89 } 90 91 void solve() 92 { 93 for (int i=1;i<=2*m;i++) if (!instack[i]) tarjan(i); 94 int f=1; 95 for (int i=1;i<=m;i++) 96 if (col[i]==col[i+m]) 97 { 98 f=0; 99 break; 100 } 101 if (f) cout<<"YES"<<endl; 102 else cout<<"NO"<<endl; 103 } 104 105 int main() 106 { 107 int T; 108 scanf("%d",&T); 109 while (T--) 110 { 111 init(); 112 if (m<=3*n-6)//平面图定理 113 { 114 build(); 115 solve(); 116 } 117 else 118 cout<<"NO"<<endl; 119 } 120 return 0; 121 }
时间: 2024-10-12 13:03:09