zoukankan      html  css  js  c++  java
  • [洛谷P1407][国家集训队]稳定婚姻

    题目大意:有$n$对夫妻和$m$对情人,如果一对情人中的两人都离婚了,那么他们可以结为夫妻。对于每一对夫妻,若他们离婚后所有人依然可以结婚,那么就是不安全的,否则是安全的。问每一对夫妻是否安全。

    题解:考虑$tarjan$缩点。把图转成有向图,夫妻之间$G->B$,情人之间$B->G$,$tarjan$缩点,最后判断每一对夫妻是否在同一个强连通分量内($size>1$),如果在就是不安全(连成了一个环),反之安全。

    卡点:1.$tarjan$中当$DFN_v$访问过时,未判断$v$是否在$stack$内



    C++ Code:

    #include <cstdio>
    #include <iostream>
    #include <map>
    #define PIS pair<int, string>
    #define MP make_pair
    #define maxn 8010
    #define maxm 40010
    using namespace std;
    map<string, int> name;
    int n, nn, m, name_idx;
    string name_p[maxn];
    
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt;
    } e[maxm << 1];
    void add(int a, int b) {
    	e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    }
    
    int DFN[maxn], low[maxn], stack[maxn], tot, idx;
    int res[maxn], res_idx, sz[maxn];
    bool ins[maxn];
    inline int min(int a, int b) {return a < b ? a : b;}
    void tarjan(int u) {
    	int v;
    	DFN[u] = low[u] = ++idx;
    	ins[stack[++tot] = u] = true;
    	for (int i = head[u]; i; i = e[i].nxt) {
    		v = e[i].to;
    		if (!DFN[v]) {
    			tarjan(v);
    			low[u] = min(low[u], low[v]);
    		} else if (ins[v]) low[u] = min(low[u], DFN[v]);
    	}
    	if (DFN[u] == low[u]) {
    		res_idx++;
    		int siz = 0;
    		do {
    			ins[v = stack[tot--]] = false;
    			res[v] = res_idx; siz++;
    		} while (v != u);
    		sz[res_idx] = siz;
    	}
    }
    
    int main() {
    	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    	cin >> n; nn = n << 1;
    	for (int i = 0; i < n; i++) {
    		string a, b;
    		cin >> a >> b;
    		name_p[++idx] = a;
    		name.insert(MP(a, idx));
    		name_p[++idx] = b;
    		name.insert(MP(b, idx));
    		add(idx - 1, idx);
    	}
    	cin >> m;
    	for (int i = 0; i < m; i++) {
    		string a, b;
    		cin >> a >> b;
    		add(name[b], name[a]);
    	}
    	for (int i = 1; i <= nn; i++) {
    		if (!DFN[i]) tarjan(i);
    	}
    	for (int i = 1; i <= n; i++) {
    		if (sz[res[i << 1]] > 1) puts("Unsafe");
    		else puts("Safe");
    	}
    	return 0;
    }
    
  • 相关阅读:
    教研室课题卫星通信系统
    html5学习笔记03. Canvas简介,Canvas的使用方法
    ARCGIS RUNTIME FOR IOS总结(一)
    ARCGIS RUNTIME FOR IOS总结(三)
    html5学习笔记05.JavaScript 中的面向对象,继承和封装
    JAVA排序算法之 选择排序
    ARCGIS RUNTIME FOR IOS总结(六)
    ASP upload
    问题一百三十:字符矩阵排序
    美妙的微机原理2013/5/1
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9525675.html
Copyright © 2011-2022 走看看