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

      最喜欢这样的题了(最近越来越发现自己对图论的热爱)~

      也可能是因为这种题好写。。。

      但是对自己没有一次AC表示不舒服。

      原因是数组开小了(emmm……)……

      言归正传:

      首先是图的存法,由于要够成环,所以夫妻之间的边和情侣之间的边方向一定是相反的(因为对于无向图的写法我没太大把握),至于具体方向无所谓,只要相反,就行。

      然后我们的可爱的Tarjan一遍遍地跑呀跑……

      看一遍,如果情侣在一个强连通分量里,自然就是不安全的,反之安全。

      有一个小技巧:

      一开始我是枚举边并且判断是否为情侣,还要开数组记下来谁是谁的情侣,判断很麻烦。

      切掉之后我看了一眼题解,发现意外收获:就是我们可以规定一对情侣之间的序号相差n(这样肯定没有重叠嘛),这样判断的时候,判断 i 和 i + n 即可。

      好了直接上代码:

    #include<cstdio>
    #include<iostream>
    #include<map>
    using namespace std;
    #define maxn 500005
    int low[50000],dfn[50000],head[50000],co[50000],to[maxn],nxt[maxn],st[maxn];
    int cnt,n,m,col,num,top;
    map<string,int> q;
    void add(int a,int b)
    {
        to[++cnt]=b;
        nxt[cnt]=head[a];
        head[a]=cnt;
    }
    void Tarjan(int u)
    {
        dfn[u]=low[u]=++num;
        st[++top]=u;
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(!dfn[v])
            {
                Tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(!co[v])
            low[u]=min(dfn[v],low[u]);
        }
        if(low[u]==dfn[u])
        {
            co[u]=++col;
            while(st[top]!=u)
            {
                co[st[top]]=col;
                top--;
            }
            top--;
        }
    }
    int main()
    {
        scanf("%d",&n);
        string gir,boy;
        for(int i=1;i<=n;i++)
        {
            cin>>gir>>boy;
            q[gir]=i;
            q[boy]=i+n;
            add(i,i+n);
        }
        scanf("%d",&m); 
        for(int i=1;i<=m;i++)
        {
            cin>>gir>>boy;
            add(q[boy],q[gir]);
        }
        for(int i=1;i<=2*n;i++)
        if(!dfn[i]) Tarjan(i);
        for(int i=1;i<=n;i++)
        if(co[i]==co[i+n]) printf("Unsafe
    ");
        else printf("Safe
    ");
        return 0;
    }
  • 相关阅读:
    golang学习----nil值
    CentOS配置multipath
    oracle基础-创建表空间
    oracle数据库基本命令
    CentOS使用fdisk扩展磁盘空间
    CentOS增加swap分区
    VMWARE错误-"VirtualInfrastructure.Utils.ClientsXml"的类型初始值设定项引发异常
    windows server 2008远程桌面最大连接数设置
    windows sserver 2008远程桌面端口修改
    iSCSI配置
  • 原文地址:https://www.cnblogs.com/popo-black-cat/p/10147166.html
Copyright © 2011-2022 走看看