POJ - 3207 Ikki's Story IV - Panda's Trick(2-SAT)

来源:互联网 发布:如何看java源码 编辑:程序博客网 时间:2024/06/01 10:08

题目大意:有一个圈,圈上面按顺时针摆满了1-N,现在有M条连线(两点连线,连线可以为曲线,可以在圈内连线,也可在圈外连线),问这些连线是否相交

解题思路:判断相交的话,只需要判断线的区间是否相交即可

#include <cstdio>#include <cstring>#include <vector>using namespace std;#define M 1010struct link{    int x, y;}L[M];int n, m, top;int S[M];bool mark[M];vector<int> G[M];void AddEdge(int x, int valx, int y, int valy) {    x = x * 2 + valx;    y = y * 2 + valy;    G[x].push_back(y);}void init() {    for (int i = 0; i < m; i++) {        scanf("%d%d", &L[i].x, &L[i].y);        if (L[i].x > L[i].y) {            L[i].x = L[i].y ^ L[i].x;            L[i].y = L[i].y ^ L[i].x;            L[i].x = L[i].y ^ L[i].x;        }    }    for (int i = 0; i < 2 * m; i++)         G[i].clear();    for (int i = 0; i < m; i++)        for (int j = i + 1; j < m; j++) {            if ((L[i].x < L[j].x && L[i].y < L[j].y && L[i].y > L[j].x) || (L[i].x > L[j].x && L[i].y > L[j].y && L[i].x < L[j].y)) {                AddEdge(i, 0, j, 1);                AddEdge(i, 1, j, 0);                AddEdge(j, 0, i, 1);                AddEdge(j, 1, i, 0);            }        }}bool dfs(int u) {    if (mark[u ^ 1])        return false;    if (mark[u])        return true;    mark[u] = true;    S[++top] = u;    for (int i = 0; i < G[u].size(); i++)        if (!dfs(G[u][i]))            return false;    return true;}void solve() {    memset(mark, 0, sizeof(mark));    for (int i = 0; i < 2 * m; i += 2) {        top = 0;        if (!dfs(i)) {            while (top) mark[S[top--]] = false;            if (!dfs(i ^ 1)) {                printf("the evil panda is lying again\n");                return ;            }        }    }    printf("panda is telling the truth...\n");}int main() {    scanf("%d%d", &n, &m);    init();    solve();    return 0;}
0 0
原创粉丝点击