3207

1 /*
2 2SAT验证题目。对边进行构图,边最多500条,分别判断每两条边是否能够相交
3 如果相交,加限制条件,和3678很相似
4 */
5
6 // include file
7 #include <cstdio>
8 #include <cstdlib>
9 #include <cstring>
10 #include <cmath>
11 #include <cctype>
12 #include <ctime>
13
14 #include <iostream>
15 #include <sstream>
16 #include <fstream>
17 #include <iomanip>
18 #include <bitset>
19 #include <strstream>
20
21 #include <algorithm>
22 #include <string>
23 #include <vector>
24 #include <queue>
25 #include <set>
26 #include <list>
27 #include <functional>
28
29 using namespace std;
30
31 // typedef
32 typedef long long LL;
33 typedef unsigned long long ULL;
34
35 //
36 #define read freopen("in.txt","r",stdin)
37 #define write freopen("out.txt","w",stdout)
38 #define FORi(a,b) for(int i=(a);i<(b);i++)
39 #define FORj(a,b) for(int j=(a);j<(b);j++)
40
41 #define FF(i,a) for(int i=0;i<(a);i+++)
42 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
43 #define Z(a) (a<<1)
44 #define Y(a) (a>>1)
45
46 const double eps = 1e-11;
47 const double Pi = acos(-1.0);
48
49 template<class T> inline T sqr(T a){return a*a;}
50 template<class T> inline T TMAX(T x,T y)
51 {
52 if(x>y) return x;
53 return y;
54 }
55 template<class T> inline T TMIN(T x,T y)
56 {
57 if(x<y) return x;
58 return y;
59 }
60 template<class T> inline T MMAX(T x,T y,T z)
61 {
62 return TMAX(TMAX(x,y),z);
63 }
64
65 // code begin
66 #define MAXN 2010
67
68 struct node
69 {
70 int a,b;
71 }edge[MAXN];
72 vector<int> G[MAXN];
73
74 int scc;
75 int cnt;
76 int used[MAXN];
77 int stk1[MAXN],top1;
78 int stk2[MAXN],top2;
79 int isin[MAXN];
80 int dfn[MAXN];
81 int id[MAXN];
82 int N,M;
83
84 bool checkinsec(int i,int j)
85 {
86 int imin = TMIN(edge[i].a,edge[i].b);
87 int imax = TMAX(edge[i].a,edge[i].b);
88 int jmin = TMIN(edge[j].a,edge[j].b);
89 int jmax = TMAX(edge[j].a,edge[j].b);
90 // 能否找到不相交的情况
91 if( (jmin>=imin && jmin<=imax) && (jmax<imin || jmax>imax) ) return true;
92 if( jmin<imin && jmin>imax && (jmax>=imin || jmax<=imax) ) return true;
93 return false;
94 }
95
96 void gabow_scc(int i)
97 {
98 used[i] = true;
99 stk1[top1++] = i;
100 stk2[top2++] = i;
101 dfn[i] = cnt++;
102 isin[i] = true;
103
104 FORj( 0,G[i].size() )
105 {
106 if(!used[ G[i][j] ])
107 {
108 gabow_scc(G[i][j]);
109 }
110 else if(isin[G[i][j]])
111 {
112 while(dfn[stk2[top2-1]]>dfn[G[i][j]])
113 top2--;
114 }
115 }
116
117 if(i==stk2[top2-1])
118 {
119 top2--;
120 int w;
121 do
122 {
123 w = stk1[--top1];
124 isin[w] = false;
125 id[w] = scc;
126 }while(w!=i);
127
128 scc++;
129 }
130 }
131
132 int main()
133 {
134 read;
135 write;
136 scanf("%d %d",&N,&M);
137
138 FORi(0,2*M)
139 {
140 G[i].clear();
141 }
142 //建图
143 int a,b;
144 FORi(0,M)
145 {
146 scanf("%d %d",&edge[i].a,&edge[i].b);
147 }
148 FORi(0,M)
149 {
150 FORj(i+1,M)
151 {
152 //printf("%d %d",i,j);
153 if( checkinsec(i,j) )
154 {
155 //printf("相交");
156 // 2*i 2*j
157 // 2*i+1 2*j+1
158 G[2*i].push_back(2*j+1);
159 G[2*j+1].push_back(2*i);
160
161 G[2*i+1].push_back(2*j);
162 G[2*j].push_back(2*i+1);
163 }
164 //printf("\n");
165 }
166 }
167
168 // 运行gabow_scc
169 memset(used,0,sizeof(used));
170 memset(id,0,sizeof(used));
171 cnt = 1;
172 scc = 1;
173 top1 = top2 = 0;
174 FORi(0,2*M)
175 {
176 if(!used[i])
177 {
178 gabow_scc(i);
179 }
180 }
181
182 // 验证是否有2sat解
183 bool f = true;
184 FORi(0,M)
185 {
186 if( id[i*2]==id[i*2+1] )
187 {
188 f=false;
189 break;
190 }
191 }
192 if(f) printf("panda is telling the truth...\n");
193 else printf("the evil panda is lying again\n");
194
195 return 0;
196 }
posted @ 2011-02-28 19:29  AC2012  阅读(295)  评论(0编辑  收藏  举报