原题链接
- 题解:不要看到多重关系就慌张,其实本质上还是一对一对的关系,所以要提取出来,关键不得不做的信息,然后建图。
- 代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 2e6 + 9;
const int M = 2e6 + 9;
int h[N], ne[M], to[M], idx;
void add(int u, int v) {
ne[idx] = h[u], to[idx] = v, h[u] = idx++;
}
int dfn[N], low[N], times;
int sz[N], id[N], scc_cnt;
int stk[N], instk[N], top;
void tarjan(int u) {
dfn[u] = low[u] = times++;
stk[++top] = u;
instk[u]= 1;
for (int i = h[u]; ~i; i = ne[i]) {
int v = to[i];
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (instk[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if (low[u] == dfn[u]){
scc_cnt++;
while (1) {
int v = stk[top];
top--;
instk[v] = 0;
id[v] = scc_cnt;
sz[scc_cnt] ++;
if (v == u)break;
}
}
}
int n, m;
void solve() {
double l = 0, r =
memset(h, -1, sizeof h);
idx = 0;
memset(dfn, 0, sizeof dfn);
scc_cnt = 0;
times = 0;
int nn = n;n *=3;
for (int i = 1; i <= nn; i ++) {
int u, v, k;scanf("%d%d%d", &u, &v, &k);
u++,v++,k++;
add(u, v + n);
add(u, k + n);
add(v, u + n);
add(k, u + n);
add(k + n, v + n);//关键,好好想想
add(v + n, k + n);//关键
}
while (m--) {
int u, v;
scanf("%d%d", &u, &v);
u++, v++;
add(u + 1 * n, v );
add(v + 1 * n, u );
}
for (int i = 1; i <= 2 * n; i++) {
if (!dfn[i]) tarjan(i);
}
for (int i = 1; i <= n; i++) {
if (id[i] == id[i + n]) {
puts("no");
return;
}
}
puts("yes");
}
int main() {
while (~scanf("%d", &n)) {
solve();
}
}