zoukankan      html  css  js  c++  java
  • 「国家集训队」稳定婚姻

    「国家集训队」稳定婚姻

    传送门
    考虑把男生看成黑点,女生看成白点。
    那么一对不稳定的婚姻存在,当且仅当夫妻双方位于同一个黑白相间的环上。
    然后我们考虑构造:
    婚姻关系由女向男连边,情侣关系由男向女连边,那么一对不稳定婚姻就对应了有向图中的一个环。
    那么我们直接跑一遍缩点即可。
    参考代码:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    #define rg register
    #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
    using namespace std;
    
    const int _ = 2 * 4010, __ = 4010 + 20010;
    
    int tot, head[_], nxt[__], ver[__];
    inline void Add_edge(int u, int v)
    { nxt[++tot] = head[u], head[u] = tot, ver[tot] = v; }
    
    string s, t, a[_ / 2], b[_ / 2];
    map < string, int > p;
    int n, m, node, num, dfn[_], low[_], col, co[_], top, stk[_];
    
    inline void tarjan(int u) {
    	low[u] = dfn[u] = ++num, stk[++top] = u;
    	for (rg int i = head[u]; i; i = nxt[i]) {
    		int v = ver[i];
    		if (!dfn[v])
    			tarjan(v), low[u] = min(low[u], low[v]);
    		else
    			if (!co[v]) low[u] = min(low[u], dfn[v]);
    	}
    	if (low[u] == dfn[u]) {
    		++col;
    		do co[stk[top]] = col; while (stk[top--] != u);
    	}
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	file("cpp");
    #endif
    	scanf("%d", &n);
    	for (rg int i = 1; i <= n; ++i) {
    		cin >> a[i] >> b[i];
    		if (!p[a[i]]) p[a[i]] = ++node;
    		if (!p[b[i]]) p[b[i]] = ++node;
    		Add_edge(p[b[i]], p[a[i]]);
    	}
    	scanf("%d", &m);
    	for (rg int i = 1; i <= m; ++i)
    		cin >> s >> t, Add_edge(p[s], p[t]);
    	for (rg int i = 1; i <= node; ++i) if (!dfn[i]) tarjan(i);
    	for (rg int i = 1; i <= n; ++i)
    		puts(co[p[a[i]]] == co[p[b[i]]] ? "Unsafe" : "Safe");
    	return 0;
    }
    
  • 相关阅读:
    Go语言标准库flag基本使用
    GO学习-(12) Go语言基础之函数
    GO学习-(11) Go语言基础之map
    GO学习-(10) Go语言基础之指针
    Spring AOP
    JDK动态代理
    版本控制
    版本控制
    浅析Java反射机制
    Spring Batch学习
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/12231621.html
Copyright © 2011-2022 走看看