POJ3207+tarjan+2-sat
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 2-sat 3 题意:给定一个圆,圆上一些点。两点一线。现给出一些线,这些线可以在圆内连起来,也可以在圆外。 4 问有没有可能所有的线画完 且 不出现相交。 5 思路:把线画在圆内或圆外 看成一个组合。其它的则建边。 6 */ 7 #include<stdio.h> 8 #include<string.h> 9 #include<stdlib.h> 10 #include<math.h> 11 #include<algorithm> 12 #include<iostream> 13 #include<set> 14 #include<stack> 15 #include<queue> 16 #include<map> 17 #include<vector> 18 using namespace std; 19 20 typedef long long int64; 21 //typedef __int64 int64; 22 typedef pair<int64,int64> PII; 23 #define MP(a,b) make_pair((a),(b)) 24 const int maxn = 2225; 25 const int maxm = 250000; 26 const int inf = 0x7fffffff; 27 const double pi=acos(-1.0); 28 const double eps = 1e-8; 29 30 struct Edge{ 31 int u,v,next; 32 }edge[ maxm*2+5 ]; 33 int cnt,head[ maxn ]; 34 int vis[ maxn ]; 35 int dfn[ maxn ],low[ maxn ]; 36 int belong[ maxn ],Cnt,id; 37 stack<int>s; 38 struct EDGE{ 39 int l,r; 40 }E[ maxn ]; 41 42 void init(){ 43 id = Cnt = 0; 44 cnt = 0; 45 while( !s.empty() ) 46 s.pop(); 47 memset( head,-1,sizeof( head ) ); 48 memset( vis,-1,sizeof( vis ) ); 49 memset( dfn,-1,sizeof( dfn ) ); 50 memset( low,-1,sizeof( low ) ); 51 } 52 53 void addedge( int a,int b ){ 54 edge[ cnt ].u = a; 55 edge[ cnt ].v = b; 56 edge[ cnt ].next = head[ a ]; 57 head[ a ] = cnt++; 58 } 59 60 bool ok( int L,int R ){ 61 int x1 = E[L].l; 62 int y1 = E[L].r; 63 int x2 = E[R].l; 64 int y2 = E[R].r; 65 if( x2>x1&&x2<y1 ){ 66 if( y2>=y1 ) return true; 67 if( y2<=x1 ) return true; 68 } 69 if( y2>x1&&y2<y1 ){ 70 if( x2>=y1 ) return true; 71 if( x2<=x1 ) return true; 72 } 73 return false; 74 } 75 76 void tarjan( int cur ){ 77 dfn[ cur ] = low[ cur ] = id++; 78 vis[ cur ] = 1; 79 s.push( cur ); 80 for( int i=head[ cur ];i!=-1;i=edge[i].next ){ 81 int nxt = edge[ i ].v; 82 if( dfn[ nxt ]==-1 ){ 83 tarjan( nxt ); 84 low[ cur ] = min( low[ cur ],low[ nxt ] ); 85 } 86 else if( vis[ nxt ]==1 ){ 87 low[ cur ] = min( low[ cur ],dfn[ nxt ] ); 88 } 89 } 90 if( dfn[ cur ]==low[ cur ] ){ 91 Cnt ++; 92 while( 1 ){ 93 int tmp = s.top(); 94 s.pop(); 95 vis[ tmp ] = 0; 96 belong[ tmp ] = Cnt; 97 if( tmp==cur ) break; 98 } 99 } 100 } 101 102 int main(){ 103 int n,m; 104 while( scanf("%d%d",&n,&m)==2 ){ 105 init(); 106 int a,b; 107 for( int i=1;i<=m;i++ ){ 108 scanf("%d%d",&a,&b); 109 a++,b++; 110 E[ i ].l = min( a,b ); 111 E[ i ].r = max( a,b ); 112 } 113 for( int i=1;i<=m;i++ ){ 114 for( int j=i+1;j<=m;j++ ){ 115 if( ok( i,j )==true ){ 116 addedge( i,j+m ); 117 addedge( j+m,i ); 118 addedge( i+m,j ); 119 addedge( j,i+m ); 120 } 121 } 122 }//build mat 123 for( int i=1;i<=2*m;i++ ){ 124 if( dfn[i]==-1 ){ 125 tarjan( i ); 126 } 127 } 128 // 129 bool f = true; 130 for( int i=1;i<=m;i++ ){ 131 if( belong[i]==belong[i+m] ){ 132 f = false; 133 break; 134 } 135 } 136 if( f==false ) printf("the evil panda is lying again"); 137 else printf("panda is telling the truth..."); 138 printf("\n"); 139 } 140 return 0; 141 }
keep moving...