hdu 1824

2-sat

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



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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值