• #Tarjan#洛谷 1407 [国家集训队]稳定婚姻


    题目


    分析

    如果婚姻安全那么两个点不在同一个强连通分量,
    考虑强制定方向,夫妻女向男连边,情侣男向女连边,
    这样就直接用Tarjan有向图缩点就可以了


    代码

    #include <iostream>
    #include <string>
    #include <stack>
    #include <map>
    #define rr register
    using namespace std;
    const int N=8011; stack<int>stac; map<string,int>uk;
    struct node{int y,next;}e[N<<2]; string S,T;
    int as[N],low[N],dfn[N],col[N],k,v[N],n,tot,cnt,m;
    inline void add(int x,int y){e[++k]=(node){y,as[x]},as[x]=k;}
    inline void tarjan(int x){
    	dfn[x]=low[x]=++tot;
    	stac.push(x); v[x]=1;
    	for (rr int i=as[x];i;i=e[i].next)
    	if (!dfn[e[i].y]){
    		tarjan(e[i].y);
    		low[x]=min(low[x],low[e[i].y]);
    	}
    	else if (v[e[i].y])
    	    low[x]=min(low[x],dfn[e[i].y]);
    	if (dfn[x]==low[x]){
    		++cnt; rr int y;
    		do{
    			y=stac.top(); stac.pop();
    			v[y]=0; col[y]=cnt;
    		}while (x!=y);
    	}
    }
    signed main(){
    	ios::sync_with_stdio(0),
    	cin.tie(0),cout.tie(0);
    	cin>>n;
    	for (rr int i=1;i<=n;++i)
    		cin>>S>>T,add(uk[S]=i,uk[T]=i+n);
    	cin>>m;
    	for (rr int i=1;i<=m;++i)
    		cin>>S>>T,add(uk[T],uk[S]);
    	for (rr int i=1;i<=n*2;++i)
    	    if (!dfn[i]) tarjan(i);
    	for (rr int i=1;i<=n;++i)
    	if (col[i]^col[i+n]) cout<<"Safe"<<endl;
    	    else cout<<"Unsafe"<<endl;
    	return 0;
    }
    
  • 相关阅读:
    活动安排问题
    CodeForces
    HDU
    HDU
    HihoCoder
    二分签到题--二分入门
    并查集,最小生成树
    spark和 mapreduce的比较
    SparkSQL--数据源Parquet的加载和保存
    SparkSQL -DataFrame与RDD的互转
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13922246.html
Copyright © 2020-2023  润新知