poj 3905

2-sat 只需要简单建图即可。

View Code
 1 #include<iostream>
2 #include<vector>
3 #include<cstring>
4 #include<cstdio>
5 #include<algorithm>
6 using namespace std;
7 const int maxn=20001;
8 vector<int>edge[maxn];
9 int st[maxn];
10 int dfn[maxn],low[maxn];
11 int top,btype,tdfn;
12 int belong[maxn];
13 bool ins[maxn];
14 int bob,alice[maxn];
15 int n,m,a,b;
16 void dfs(int s)
17 {
18 int t;
19 dfn[s]=low[s]=++tdfn;
20 ins[s]=1;
21 st[++top]=s;
22 for(int i=0;i<edge[s].size();i++)
23 {
24 int t=edge[s][i];
25 if(!dfn[t])
26 {
27 dfs(t);
28 if(low[t]<low[s])
29 low[s]=low[t];
30 }
31 else if(ins[t]&&dfn[t]<low[s])
32 low[s]=dfn[t];
33 }
34 if(dfn[s]==low[s])
35 {
36 btype++;
37 do
38 {
39 t=st[top--];
40 ins[t]=0;
41 belong[t]=btype;
42 }while(t!=s);
43 }
44 }
45 void scc(int n)
46 {
47 top=btype=tdfn=0;
48 memset(ins,0,sizeof(ins));
49 memset(dfn,0,sizeof(dfn));
50 for(int i=1;i<=n;i++)
51 if(!dfn[i])
52 dfs(i);
53 }
54 int main()
55 {
56 int ta,tb;
57 while(scanf("%d%d",&n,&m)!=EOF)
58 {
59 for(int i=0;i<=2*n;i++)
60 edge[i].clear();
61 for(int i=0;i<m;i++)
62 {
63 scanf("%d%d",&a,&b);
64 if(a>0&&b>0)
65 {
66 edge[a+n].push_back(b);
67 edge[b+n].push_back(a);
68 }
69 if(a<0&&b<0)
70 {
71 edge[-a].push_back(-b+n);
72 edge[-b].push_back(-a+n);
73 }
74 if(a>0&&b<0)
75 {
76 edge[a+n].push_back(-b+n);
77 edge[-b].push_back(a);
78 }
79 if(a<0&&b>0)
80 {
81 edge[b+n].push_back(-a+n);
82 edge[-a].push_back(b);
83 }
84 }
85 scc(2*n);
86 bool flag=true;
87 for(int i=1;i<=n;i++)
88 if(belong[i]==belong[i+n])
89 flag=false;
90 if(flag) printf("1\n");
91 else printf("0\n");
92 }
93 return 0;
94 }



转载于:https://www.cnblogs.com/xuschang-93/archive/2012/03/17/2403325.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值