码迷,mamicode.com
首页 > 其他好文 > 详细

LUOGU P1407 [国家集训队]稳定婚姻

时间:2018-10-11 18:50:55      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:unsafe   include   put   style   www   code   lse   scanf   view   

传送门

 

解题思路

让所有夫妇之间连男到女的边,所有情人之间连女到男的边,然后用$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

 

LUOGU P1407 [国家集训队]稳定婚姻

标签:unsafe   include   put   style   www   code   lse   scanf   view   

原文地址:https://www.cnblogs.com/sdfzsyq/p/9773738.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!