# HDU 1824 Let's go home （2-SAT判定）

u013967323 · · 1442 次点击 · · 开始浏览

# Let's go home

Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1616    Accepted Submission(s): 661

Problem Description

—— 余光中

Input

Output

Sample Input
```1 2
0 1 2
0 1
1 2

2 4
0 1 2
3 4 5
0 3
0 4
1 3
1 4```

Sample Output
```yes
no```

Author

Source

2-SAT就是两者有冲突就连边。
```#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <stack>
#include <set>
#include <map>
#define LL long long
using namespace std;
const int MAXN = 20010;
vector<int>G[MAXN];
int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt;
stack<int> s;
void dfs(int u)
{
s.push(u); int sz = G[u].size();
for(int i=0;i<sz;i++)
{
int v = G[u][i];
if(!pre[v])
{
dfs(v);
}
else if(!sccno[v])
{
}
}
{
scc_cnt++;
for(;;)
{
int x = s.top(); s.pop();
sccno[x] = scc_cnt;
if(x == u) break;
}
}
}
void find_scc(int n)
{
dfs_clock = scc_cnt = 0;
memset(sccno, 0, sizeof(sccno));
memset(pre, 0, sizeof(pre));
for(int i=1;i<=n;i++) if(!pre[i])
dfs(i);
}
int N, M, T;
int main()
{
while(scanf("%d%d", &T, &M)!=EOF)
{
int x, y, z;
N = 3 * T;
for(int i=0;i<=2*N;i++) G[i].clear();
for(int i=1;i<=T;i++)
{
scanf("%d%d%d", &x, &y, &z);
x++; y++; z++;
G[x+N].push_back(y);
G[x+N].push_back(z);
G[y+N].push_back(x);
G[z+N].push_back(x);
}
for(int i=1;i<=M;i++)
{
scanf("%d%d", &x, &y);
x++; y++;
G[x].push_back(y + N);
G[y].push_back(x + N);
}
find_scc(2 * N);
int flag = 1;
for(int i=1;i<=N;i++)
{
if(sccno[i] == sccno[i + N])
{
flag = 0;
break;
}
}
if(flag) puts("yes");
else puts("no");
}
return 0;
}```

0 回复

• 请尽量让自己的回复能够对别人有帮助
• 支持 Markdown 格式, **粗体**、~~删除线~~、``单行代码``
• 支持 @ 本站用户；支持表情（输入 : 提示），见 Emoji cheat sheet
• 图片支持拖拽、截图粘贴等方式上传

# Let's go home

Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1616    Accepted Submission(s): 661

Problem Description

—— 余光中

Input

Output

Sample Input
```1 2
0 1 2
0 1
1 2

2 4
0 1 2
3 4 5
0 3
0 4
1 3
1 4```

Sample Output
```yes
no```

Author

Source

2-SAT就是两者有冲突就连边。
```#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <stack>
#include <set>
#include <map>
#define LL long long
using namespace std;
const int MAXN = 20010;
vector<int>G[MAXN];
int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt;
stack<int> s;
void dfs(int u)
{
s.push(u); int sz = G[u].size();
for(int i=0;i<sz;i++)
{
int v = G[u][i];
if(!pre[v])
{
dfs(v);
}
else if(!sccno[v])
{
}
}
{
scc_cnt++;
for(;;)
{
int x = s.top(); s.pop();
sccno[x] = scc_cnt;
if(x == u) break;
}
}
}
void find_scc(int n)
{
dfs_clock = scc_cnt = 0;
memset(sccno, 0, sizeof(sccno));
memset(pre, 0, sizeof(pre));
for(int i=1;i<=n;i++) if(!pre[i])
dfs(i);
}
int N, M, T;
int main()
{
while(scanf("%d%d", &T, &M)!=EOF)
{
int x, y, z;
N = 3 * T;
for(int i=0;i<=2*N;i++) G[i].clear();
for(int i=1;i<=T;i++)
{
scanf("%d%d%d", &x, &y, &z);
x++; y++; z++;
G[x+N].push_back(y);
G[x+N].push_back(z);
G[y+N].push_back(x);
G[z+N].push_back(x);
}
for(int i=1;i<=M;i++)
{
scanf("%d%d", &x, &y);
x++; y++;
G[x].push_back(y + N);
G[y].push_back(x + N);
}
find_scc(2 * N);
int flag = 1;
for(int i=1;i<=N;i++)
{
if(sccno[i] == sccno[i + N])
{
flag = 0;
break;
}
}
if(flag) puts("yes");
else puts("no");
}
return 0;
}```