首先用一波神奇的操作,平面图边数m<=3*n-6,直接把m降到n,
然后对于冲突的边一条环内,一条环外,可以用并查集或者2Sat做,
当然并查集是无向的,2Sat是有向的,显然用并查集比较好 复杂度大概是O(T*n*n)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #define pb push_back 6 #define pii pair<int,int> 7 #define ft first 8 #define sc second 9 #define MAXN 200000+10 10 using namespace std; 11 int n,m; 12 int b[MAXN],d[MAXN],f[MAXN]; 13 pii E[MAXN]; 14 int find(int x){return (f[x]==x?x:f[x]=find(f[x]));} 15 void init_find(){ 16 for(int i=1;i<=(m<<1);i++)f[i]=i; 17 } 18 void lik(int x,int y){ 19 x=find(x),y=find(y); 20 if(x!=y)f[x]=y; 21 } 22 int solve(){ 23 scanf("%d%d",&n,&m); 24 init_find(); 25 for(int i=1;i<=m;i++)scanf("%d%d",&E[i].ft,&E[i].sc); 26 int t; 27 for(int i=1;i<=n;i++)scanf("%d",&t),d[t]=i; 28 if(m>3*n-6)return 0; 29 memset(b,0,sizeof(b)); 30 for(int i=1;i<=m;i++){ 31 E[i].ft=d[E[i].ft],E[i].sc=d[E[i].sc]; 32 if(E[i].ft>E[i].sc){swap(E[i].ft,E[i].sc);} 33 if(E[i].sc-E[i].ft==1||E[i].sc-E[i].ft==n-1)b[i]=1; 34 } 35 pii x,y; 36 for(int i=1;i<=m;i++){ 37 if(b[i])continue; 38 for(int j=i+1;j<=m;j++){ 39 if(b[j])continue; 40 x=E[i],y=E[j]; 41 if(x.ft==y.ft||x.ft==y.sc)continue; 42 if(x.sc==y.ft||x.sc==y.sc)continue; 43 if(x.ft==x.sc||y.ft==y.sc)continue; 44 if(x.ft>y.ft)swap(x,y); 45 if(y.ft<x.sc&&x.sc<y.sc){ 46 if(find(i)==find(j))return 0; 47 lik(i,j+m),lik(j,i+m); 48 } 49 } 50 } 51 return 1; 52 } 53 int main() 54 { 55 // freopen("data.in","r",stdin); 56 int T; 57 scanf("%d",&T); 58 while(T--){ 59 if(solve())printf("YES "); 60 else printf("NO "); 61 } 62 return 0; 63 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #define pb push_back 6 #define pii pair<int,int> 7 #define ft first 8 #define sc second 9 #define MAXN 200000+10 10 using namespace std; 11 struct TSat{ 12 int n; 13 int fst[MAXN],nxt[MAXN],to[MAXN]; 14 int cnt; 15 void add(int x,int y){ 16 nxt[++cnt]=fst[x],fst[x]=cnt,to[cnt]=y; 17 } 18 void ins(int x,int y){ 19 add(x,y+n); 20 add(x+n,y); 21 } 22 int dfn[MAXN],low[MAXN]; 23 int cmp[MAXN],sta[MAXN],vis[MAXN],top; 24 int time_dex,tmp; 25 void init(int n){ 26 this->n=n; 27 time_dex=tmp=cnt=top=0; 28 memset(dfn,0,sizeof(dfn)); 29 memset(low,0,sizeof(low)); 30 memset(vis,0,sizeof(vis)); 31 memset(fst,0,sizeof(fst)); 32 memset(nxt,0,sizeof(nxt)); 33 memset(to,0,sizeof(to)); 34 memset(cmp,0,sizeof(cmp)); 35 } 36 void Tarjan(int x){ 37 dfn[x]=low[x]=++time_dex; 38 sta[++top]=x; 39 vis[x]=1; 40 for(int e=fst[x];e;e=nxt[e]){ 41 int &y=to[e]; 42 if(!dfn[y]){ 43 Tarjan(y); 44 low[x]=min(low[x],low[y]); 45 } 46 else if(vis[y]){ 47 low[x]=min(low[x],dfn[y]); 48 } 49 } 50 if(low[x]==dfn[x]){ 51 tmp++; 52 while(sta[top+1]!=x){ 53 cmp[sta[top]]=tmp; 54 vis[sta[top]]=0; 55 top--; 56 } 57 } 58 } 59 bool check(){ 60 for(int i=1;i<=(n<<1);i++){ 61 if(!dfn[i])Tarjan(i); 62 } 63 for(int i=1;i<=n;i++){ 64 if(cmp[i]==cmp[i+n]) 65 return 0; 66 } 67 return 1; 68 } 69 }TS; 70 int n,m; 71 int b[MAXN],d[MAXN]; 72 pii E[MAXN]; 73 int solve(){ 74 scanf("%d%d",&n,&m); 75 for(int i=1;i<=m;i++)scanf("%d%d",&E[i].ft,&E[i].sc); 76 int t; 77 for(int i=1;i<=n;i++)scanf("%d",&t),d[t]=i; 78 if(m>3*n-6)return 0; 79 TS.init(m); 80 memset(b,0,sizeof(b)); 81 for(int i=1;i<=m;i++){ 82 E[i].ft=d[E[i].ft],E[i].sc=d[E[i].sc]; 83 if(E[i].ft>E[i].sc){swap(E[i].ft,E[i].sc);} 84 if(E[i].sc-E[i].ft==1||E[i].sc-E[i].ft==n-1)b[i]=1; 85 } 86 pii x,y; 87 for(int i=1;i<=m;i++){ 88 if(b[i])continue; 89 for(int j=i+1;j<=m;j++){ 90 if(b[j])continue; 91 x=E[i],y=E[j]; 92 if(x.ft==y.ft||x.ft==y.sc)continue; 93 if(x.sc==y.ft||x.sc==y.sc)continue; 94 if(x.ft==x.sc||y.ft==y.sc)continue; 95 if(x.ft>y.ft)swap(x,y); 96 if(y.ft<x.sc&&x.sc<y.sc){ 97 TS.ins(i,j); 98 TS.ins(j,i); 99 } 100 } 101 } 102 return TS.check(); 103 } 104 int main() 105 { 106 // freopen("data.in","r",stdin); 107 int T; 108 scanf("%d",&T); 109 while(T--){ 110 if(solve())printf("YES "); 111 else printf("NO "); 112 } 113 return 0; 114 }