• BZOJ2140: 稳定婚姻


    【传送门:BZOJ2140


    简要题意:

      给出n对夫妻和他们的名字,和m对曾经互相喜欢的男女

      如果第i对夫妻发生争吵,那么这对夫妻会各自找自己喜欢的男女求安慰,而被找到的男女的另一半会因为嫉妒,也去找自己喜欢的男女求安慰,如此循环

      如果第i对夫妻发生争吵后,仍能组成n对男女,那么这段婚姻是不安全的,否则是安全的

      判断每一对夫妻的婚姻是否安全


    题解:

      二分图匹配(第一眼),O(nm)的复杂度,不要你了

      想其他方法,用强联通做

      对于原配,女连向男,对于曾经,男连向女,然后如果第i对夫妻在同一个连通块里就说明是不安全的(可以自己想一想)


    参考代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    struct trie
    {
        int c[75],s;
        trie()
        {
            s=0;
            memset(c,-1,sizeof(c));
        }
    }t[81000];int tot;
    struct node
    {
        int x,y,next;
    }a[31000];int len,last[8100];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    char st[9];
    void bt(int d)
    {
        int len=strlen(st+1),x=0;
        for(int i=1;i<=len;i++)
        {
            int y;
            if('a'<=st[i]&&st[i]<='z') y=st[i]-'a'+1+26;
            else y=st[i]-'A'+1;
            if(t[x].c[y]==-1) t[x].c[y]=++tot;
            x=t[x].c[y];
        }
        t[x].s=d;
    }
    int findid()
    {
        int len=strlen(st+1),x=0;
        for(int i=1;i<=len;i++)
        {
            int y;
            if('a'<=st[i]&&st[i]<='z') y=st[i]-'a'+1+26;
            else y=st[i]-'A'+1;
            x=t[x].c[y];
        }
        return t[x].s;
    }
    int dfn[8100],low[8100],id;
    int belong[8100],s;
    int sta[8100],tp;
    bool v[8100];
    void dfs(int x)
    {
        dfn[x]=low[x]=++id;
        sta[++tp]=x;v[x]=true;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(dfn[y]==0)
            {
                dfs(y);
                low[x]=min(low[x],low[y]);
            }
            else
            {
                if(v[y]==true) low[x]=min(low[x],dfn[y]);
            }
        }
        if(low[x]==dfn[x])
        {
            s++;int i;
            do
            {
                i=sta[tp--];
                belong[i]=s;
                v[i]=false;
            }while(i!=x);
        }
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        tot=0;
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",st+1);bt(2*i-1);
            scanf("%s",st+1);bt(2*i);
            ins(2*i,2*i-1);
        }
        int m;scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%s",st+1);x=findid();
            scanf("%s",st+1);y=findid();
            ins(x,y);
        }
        memset(v,false,sizeof(v));
        tp=id=s=0;
        memset(dfn,0,sizeof(dfn));
        for(int i=1;i<=2*n;i++)
        {
            if(dfn[i]==0) dfs(i);
        }
        for(int i=1;i<=n;i++)
        {
            if(belong[2*i-1]==belong[2*i]) printf("Unsafe
    ");
            else printf("Safe
    ");
        }
        return 0;
    }

     

  • 相关阅读:
    Chrome调试工具常用功能
    把读取sql的结果写入到excel文件
    Android逆向破解:Android Killer使用
    鸭子类型和猴子补丁
    Scrapy同时启动多个爬虫
    命令注入
    理解RESTful架构
    程序员需要谨记的九大安全编码规则
    10条建议分享:帮助你成为与硅谷工程师一样优秀的程序员
    代码审计:是安全专家都应该掌握的技能
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8633749.html
Copyright © 2020-2023  润新知