zoukankan      html  css  js  c++  java
  • [题解] [国家集训队] 稳定婚姻

    题面

    题解

    考虑在什么情况下此夫妻离婚后仍有n对夫妻

    将男性看做黑点, 女性看做白点, 情侣关系和夫妻关系看做边

    则若这对夫妻在一个黑白交错, 情侣关系和夫妻关系交错的一个环上(画图理解一下)

    这对夫妻就是不安全的

    考虑将边定向, 婚姻关系为女向男连边, 情侣关系为男向女连边

    则若夫妻都在同一个强连通分量中这对夫妻关系就是不安全的

    tarjan求强连通分量即可

    Code

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <map>
    #define N 10005
    using namespace std;
    
    int cnt, tot, num, n, m, fa[N], girl[N], boy[N], head[N], bl[N], dfn[N], low[N], stk[N], top; 
    struct edge { int to, next; } e[N << 2]; 
    map<string, int> mp;
    bool is[N]; 
    
    inline int read()
    {
    	int x = 0, w = 1; char c = getchar();
    	while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    	while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    	return x * w; 
    }
    
    inline void adde(int u, int v) { e[++tot] = (edge) { v, head[u] }; head[u] = tot; }
    
    int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
    
    void tarjan(int u, int fa)
    {
    	dfn[u] = low[u] = ++tot; stk[++top] = u; is[u] = 1;
    	for(int i = head[u]; i; i = e[i].next)
    	{
    		int v = e[i].to;
    		if(!dfn[v]) tarjan(v, u), low[u] = min(low[u], low[v]);
    		else if(v != fa && is[v]) low[u] = min(low[u], dfn[v]); 
    	}
    	if(low[u] >= dfn[u])
    	{
    		num++; 
    		while(1)
    		{
    			int now = stk[top--];
    			bl[now] = num; is[now] = 0; 
    			if(now == u) break; 
    		}
    	}
    }
    
    int main()
    {
    	n = read();
    	for(int i = 1; i <= n << 1; i++) fa[i] = i;
    	for(int i = 1; i <= n; i++)
    	{
    		string G, B; cin>>G>>B; 
    		if(!mp[G]) mp[G] = girl[i] = ++cnt;
    		if(!mp[B]) mp[B] = boy[i] = ++cnt; 
    		adde(boy[i], girl[i]); 
    	}
    	m = read();
    	for(int i = 1; i <= m; i++)
    	{
    		string G, B; cin>>G>>B;
    		adde(mp[G], mp[B]); 
    	}
    	tot = 0; 
    	for(int i = 1; i <= cnt; i++)
    		if(!dfn[i]) tarjan(i, 0);
    	for(int i = 1; i <= n; i++)
    		printf("%s
    ", bl[girl[i]] == bl[boy[i]] ? "Unsafe" : "Safe"); 
    	return 0; 
    } 
    
  • 相关阅读:
    JS键盘码值表
    JS入门笔记
    CSS居中的方法总结
    CSS布局模型思考
    条件、循环、函数定义、字符串操作练习
    Python输入输出练习,运算练习,turtle初步练习
    如何理解Comparator接口中的升降序?
    12个非常实用的JavaScript小技巧
    JAVA泛型知识(一)
    开窗函数简介
  • 原文地址:https://www.cnblogs.com/ztlztl/p/11184465.html
Copyright © 2011-2022 走看看