• 洛谷P1407 稳定婚姻(tarjan)


    题目链接:https://www.luogu.org/problemnew/show/P1407

    题目意思:有n对夫妻,有m对前男女朋友关系(都是n对夫妻中的人),问每一对夫妻是否婚姻稳定?

    婚姻不稳定是指这对夫妻离婚,分别和有旧情的前男女朋友结婚,仍可以使2*n个人构成n对夫妻。

    思路:我们将所有 现在或曾经交往过的 男孩和女孩连接起来,可以发现出现了一些环,而处在环中的几对夫妻都可以更换伴侣,也就是题目中所说的婚姻不安全。那么我们找出这些环,判断哪些夫妻处在环中即可。

    我们想到tarjan就可以,但是tarjan是在有向图上进行的。我们怎么将这个无向图连接呢?

    我们将单向边表示全部信息,而只要夫妻和情人之间建图方向相反,就可以保留原有关系了。

    这里是将:

    夫妻之间:girlboy

    情人之间:boygirl

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    map<string,int>b,g;
    const int maxn=10005;
    const int maxm=300005;
    struct node{
        int u,v,next;
    }e[maxm];
    int h[maxn],vis[maxn],low[maxn],dfn[maxn];
    int st[maxn],belong[maxn];
    int n,m,cnt,tot,top,num;
    
    void init()
    {
        memset(vis,0,sizeof(vis));
        memset(h,-1,sizeof(h));
        memset(dfn,0,sizeof(dfn));
        memset(belong,0,sizeof(belong));
        cnt=tot=top=num=0;
    }
    
    void add(int u,int v)
    {
        e[cnt].u=u;
        e[cnt].v=v;
        e[cnt].next=h[u];
        h[u]=cnt++;
    }
    
    void tarjan(int u)
    {
        low[u]=dfn[u]=++tot;
        vis[u]=1;
        st[++top]=u;
        for(int i=h[u];i!=-1;i=e[i].next)
        {
            int v=e[i].v;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(vis[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u])
        {
            int t;
            num++;
            do{
                t=st[top--];
                vis[t]=0;
                belong[t]=num;
            }while(t!=u);
        }
    }
    
    int main()
    {
        std::ios::sync_with_stdio(false);
        cin>>n;
        string boy,girl;
        init();
        for(int i=0;i<n;i++)
        {
            cin>>girl>>boy;
            b[boy]=i;
            g[girl]=i+n;
            add(i+n,i);
        }
        cin>>m;
        for(int i=0;i<m;i++)
        {
            cin>>girl>>boy;
            add(b[boy],g[girl]);
        }
        for(int i=0;i<2*n;i++)
            if(!dfn[i])
                tarjan(i);
        for(int i=0;i<n;i++)
        {
            if(belong[i]==belong[i+n])
                cout<<"Unsafe"<<endl;
            else
                cout<<"Safe"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    LeetCode "Group Shifted Strings"
    LeetCode "Read N Characters Given Read4 II
    LeetCode "Factor Combinations"
    LeetCode "Paint House II"
    LeetCode "Shortest Word Distance II"
    LeetCode "Flatten 2D Vector"
    LeetCode "Meeting Rooms II"
    iOS开发UI篇—UITableview控件使用小结
    ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
    iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
  • 原文地址:https://www.cnblogs.com/xiongtao/p/10638804.html
Copyright © 2020-2023  润新知