Poj--3207(2-SAT)
2014-10-18 17:29:09
思路:这题就是需要正确建图,其他的就是模板了。输入的时候处理下使得输入的两个点前小后大,输入完后对所有的一对边扫一遍,找出矛盾边对,建图即可。
(写这题前还是不懂tarjan为什么能够解决2-SAT问题,后来想的比较通了:比如 Si,Si’ 是拆成的一组点,显然要选其中一个,(设Si 所在的scc为 s1,Si’ 所在的scc为s2)如果选了Si 那么 s1内所有点都要选,所以如果Si、Si’在一个scc内的话就矛盾了。)
1 /*************************************************************************i 2 > File Name: 3207.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sat 18 Oct 2014 03:00:35 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 2010; 27 28 int n,m; 29 int first[maxn],next[maxn * maxn],ver[maxn * maxn],ecnt; 30 int a[maxn],b[maxn]; 31 int low[maxn],dfn[maxn],sc[maxn],scnt,tot; 32 stack<int> S; 33 34 void Add_edge(int u,int v){ 35 next[++ecnt] = first[u]; 36 ver[ecnt] = v; 37 first[u] = ecnt; 38 } 39 40 void Dfs(int p){ 41 dfn[p] = low[p] = ++tot; 42 S.push(p); 43 for(int i = first[p]; i != -1; i = next[i]){ 44 int v = ver[i]; 45 if(!dfn[v]){ 46 Dfs(v); 47 low[p] = min(low[p],low[v]); 48 } 49 else if(!sc[v]){ 50 low[p] = min(low[p],dfn[v]); 51 } 52 } 53 if(low[p] == dfn[p]){ 54 ++scnt; 55 while(1){ 56 int x = S.top(); 57 S.pop(); 58 sc[x] = scnt; 59 if(x == p) break; 60 } 61 } 62 } 63 64 bool Tarjan(){ 65 memset(low,0,sizeof(low)); 66 memset(dfn,0,sizeof(dfn)); 67 memset(sc,0,sizeof(sc)); 68 while(!S.empty()) S.pop(); 69 scnt = tot = 0; 70 int top = 2 * m; 71 for(int i = 0; i < top; ++i) 72 if(!dfn[i]) Dfs(i); 73 for(int i = 0; i < top; i += 2){ 74 if(sc[i] == sc[i + 1]) 75 return false; 76 } 77 return true; 78 } 79 80 void Init(){ 81 memset(first,-1,sizeof(first)); 82 ecnt = 0; 83 } 84 85 int main(){ 86 int x,y; 87 Init(); 88 scanf("%d%d",&n,&m); 89 for(int i = 0; i < m; ++i){ 90 scanf("%d%d",&x,&y); 91 if(x > y) swap(x,y); 92 a[i] = x; 93 b[i] = y; 94 } 95 for(int i = 0; i < m; ++i){ 96 for(int j = i + 1; j < m; ++j){ 97 if(a[i] < a[j] && a[j] < b[i] && b[i] < b[j]){ 98 Add_edge(i * 2,j * 2 + 1); 99 Add_edge(j * 2 + 1,i * 2); 100 Add_edge(i * 2 + 1,j * 2); 101 Add_edge(j * 2,i * 2 + 1); 102 } 103 } 104 } 105 if(Tarjan()) printf("panda is telling the truth...\n"); 106 else printf("the evil panda is lying again\n"); 107 return 0; 108 }

浙公网安备 33010602011771号