Let's go home HDU - 1824

原题链接

  • 题解:不要看到多重关系就慌张,其实本质上还是一对一对的关系,所以要提取出来,关键不得不做的信息,然后建图。
  • 代码:
#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();
    

}
}
posted @ 2021-04-11 11:32  u_yan  阅读(35)  评论(0编辑  收藏  举报