题目大意:有一个圈,圈上面按顺时针摆满了1-N,现在有M条连线(两点连线,连线可以为曲线,可以在圈内连线,也可在圈外连线),问这些连线是否相交
解题思路:判断相交的话,只需要判断线的区间是否相交即可
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define M 1010
struct 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;
}