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

    传送门

    解题思路

    让所有夫妇之间连男到女的边,所有情人之间连女到男的边,然后用$tarjan$,如果对于一对夫妻在强连通分量里,那么就是不稳定的,因为他们可以绕一圈。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<map>
    
    using namespace std;
    const int MAXN = 8005;
    const int MAXM = 40005;
    
    int n,m,cnt,head[MAXN],tot,to[MAXM],nxt[MAXM];
    int dfn[MAXN],low[MAXN],num,stk[MAXN],top,col[MAXN],col_num;
    bool vis[MAXN];
    string s1,s2;
    map<string,int> mp;
    
    inline void add(int bg,int ed){
        to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    void tarjan(int x){
        dfn[x]=low[x]=++num;vis[x]=1;stk[++top]=x;
        for(register int i=head[x];i;i=nxt[i]){
            int u=to[i];
            if(!dfn[u]) {tarjan(u);low[x]=min(low[x],low[u]);}
            else if(vis[u]) low[x]=min(dfn[u],low[x]);
        }
        if(dfn[x]!=low[x]) return;
        col[x]=++col_num;vis[x]=0;
        while(stk[top]!=x){
            vis[stk[top]]=0;
            col[stk[top--]]=col_num;
        }top--;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            cin>>s1>>s2;add(tot+1,tot+2);
            mp[s1]=++tot;mp[s2]=++tot;
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
            cin>>s1>>s2,add(mp[s2],mp[s1]);
        for(int i=1;i<=2*n;i++) if(!dfn[i]) tarjan(i);
        for(int i=1;i<=n;i++)
            puts(col[i<<1]==col[(i<<1)-1]?"Unsafe":"Safe");
        return 0;
    }
    View Code
  • 相关阅读:
    bzoj2946 [Poi2000]公共串(SA,SAM)
    77 最长公共子序列
    C++ lower_bound 与 upper_bound 函数
    76 最长上升子序列
    75 寻找峰值
    C++标准输入问题
    74 第一个错误的代码版本
    73 前序遍历和中序遍历树构造二叉树
    72 中序遍历和后序遍历树构造二叉树
    71 二叉树的锯齿形层次遍历
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9773738.html
Copyright © 2011-2022 走看看