Luogu P1407 [国家集训队]稳定婚姻

gate

tarjan判环,若一对夫妻在同一scc中则不稳定。

构造成有向图,

当前婚姻状况 女→男 连边,曾经交往的 男→女 连边。

代码如下

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#define MogeKo qwq
using namespace std;

const int maxn = 1e5+10;
int n,m,now,num,top,cnt;
int head[maxn],to[maxn],nxt[maxn];
int dfn[maxn],low[maxn],sta[maxn],col[maxn];
bool insta[maxn];
char u[10],v[10];
map <string,int> id;

void add(int x,int y) {
    to[++cnt] = y;
    nxt[cnt] = head[x];
    head[x] = cnt;
}

void tarjan(int u) {
    dfn[u] = low[u] = ++now;
    sta[++top] = u;
    insta[u] = true;
    for(int i = head[u]; i; i = nxt[i]) {
        int v = to[i];
        if(!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u],low[v]);
        } else if(insta[v])
            low[u] = min(low[u],dfn[v]);
    }
    if(low[u] == dfn[u]) {
        col[u] = ++num;
        insta[u] = false;
        while(sta[top] != u) {
            int v = sta[top--];
            col[v] = num;
            insta[v] = false;
        }
        top--;
    }
}

int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) {
        scanf("%s%s",u,v);
        id[u] = i*2-1;
        id[v] = i*2;
        add(id[u],id[v]);
    }
    scanf("%d",&m);
    for(int i = 1; i <= m; i++) {
        scanf("%s%s",u,v);
        add(id[v],id[u]);
    }
    for(int i = 1; i <= n*2; i++)
        if(!dfn[i])
            tarjan(i);
    for(int i = 1; i <= n; i++)
        if(col[i*2-1] == col[i*2]) printf("Unsafe
");
        else printf("Safe
");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/mogeko/p/11854038.html