码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1997: [Hnoi2010]Planar

时间:2016-03-18 07:14:29      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #define M 20005
 5 #define N 2005
 6 using namespace std;
 7 int T,n,m,head[N],next[100*M],u[100*M],x[M],y[M],pos[N],cnt,tot,c[N],dfn[N],low[N],f[N],tim,t,z[M],sum,shu[M];
 8 void tarjan(int x)
 9 {
10     f[x]=1;z[++t]=x;
11     low[x]=dfn[x]=++tim;
12     for(int i=head[x];i;i=next[i])
13         if(!dfn[u[i]])
14             tarjan(u[i]),low[x]=min(low[x],low[u[i]]);
15         else if(f[u[i]])
16             low[x]=min(low[x],dfn[u[i]]);
17     int now=-1;
18     if(low[x]==dfn[x])
19     {
20         sum++;
21         while(now!=x)
22         {
23             now=z[t--];f[now]=0;
24             shu[now]=sum;
25         }
26     }
27 }
28 void jia(int a1,int a2)
29 {
30     cnt++;
31     next[cnt]=head[a1];
32     head[a1]=cnt;
33     u[cnt]=a2;
34 }
35 bool pan()
36 {
37     for(int i=1;i<=m;i++)
38       if(shu[2*i]==shu[2*i-1])
39         return 0;
40     return 1;
41 }
42 int main()
43 {
44     scanf("%d",&T);
45     for(;T;T--)
46       {
47         scanf("%d%d",&n,&m);
48         for(int i=1;i<=m;i++)
49           scanf("%d%d",&x[i],&y[i]);
50         memset(head,0,sizeof(head));
51         sum=cnt=tim=0;
52         memset(dfn,0,sizeof(dfn));
53         memset(low,0,sizeof(low));
54         for(int i=1;i<=n;i++)
55           scanf("%d",&c[i]);
56         if(m>3*n-6)
57           {
58             printf("NO\n");
59             continue;
60           }
61         tot=0;
62         for(int i=1;i<=n;i++)
63           pos[c[i]]=i;
64         for(int i=1;i<=m;i++)
65           {
66             x[i]=pos[x[i]];
67             y[i]=pos[y[i]];
68             if(x[i]>y[i])
69               swap(x[i],y[i]);
70             if(y[i]-x[i]==1||(y[i]==n&&x[i]==1))
71               continue;
72             tot++;
73             x[tot]=x[i];
74             y[tot]=y[i];
75           }
76         m=tot;
77         for(int i=1;i<=m;i++)
78           for(int j=i+1;j<=m;j++)
79             if((x[i]<x[j]&&x[j]<y[i]&&y[i]<y[j])||(x[j]<x[i]&&x[i]<y[j]&&y[j]<y[i]))
80               {
81                 jia(i*2,j*2-1);
82                 jia(j*2-1,i*2);
83                 jia(i*2-1,j*2);
84                 jia(j*2,i*2-1);
85               }
86         for(int i=1;i<=2*m;i++)
87           if(!dfn[i])
88             tarjan(i); 
89         if(pan())
90           printf("YES\n");
91         else
92           printf("NO\n");
93       }
94     return 0;
95 }

平面图在环内顶多有n-3条,环外顶多有n-3条,环上n条,所以超过3*n-6条边一定不是平面图,然后把所有的边按哈密尔顿重新编号,判断是否相交,相交的话一定一条在外,一条在内,

这样就变成了2-set问题,用tarjin跑。

bzoj 1997: [Hnoi2010]Planar

标签:

原文地址:http://www.cnblogs.com/xydddd/p/5290307.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!