洛谷P3209 [HNOI2010]PLANAR

首先用一波神奇的操作,平面图边数m<=3*n-6,直接把m降到n,

然后对于冲突的边一条环内,一条环外,可以用并查集或者2Sat做,

当然并查集是无向的,2Sat是有向的,显然用并查集比较好 复杂度大概是O(T*n*n)

 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\n");
60         else printf("NO\n");
61     }
62     return 0;
63 }
并查集
  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\n");
111         else printf("NO\n");
112     }
113     return 0;
114 }
2Sat

 

posted @ 2018-01-10 02:02  white_hat_hacker  阅读(162)  评论(0编辑  收藏  举报