zoukankan      html  css  js  c++  java
  • BZOJ2140_稳定婚姻_KEY

    题目传送门

    暴力直接对于每个点跑一遍二分图匹配,能拿四十分。

    然而我们考虑正解。

    对于一对Couple我们建♂->♀的一条边,对于一对曾经有恋情的情侣我们建♀->♂的一条边。

    跑Tarjan缩点。

    判断每一对Couple,如果在同一个强连通分量里,他们就不稳定(即能通过曾经有恋情的关系跑回来)。

    code:

    /**************************************************************
        Problem: 2140
        User: yekehe
        Language: C++
        Result: Accepted
        Time:936 ms
        Memory:2232 kb
    ****************************************************************/
     
    #include <cstdio>
    #include <map>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    string S1,S2;
    map<string,int>MP;
    int N,M;
    struct list{
        int head[8005],nxt[45000],To[45000];
        int cnt;
        void clear(){
            memset(head,-1,sizeof head);
            memset(nxt,-1,sizeof nxt);
            cnt=0;
        }
         
        void add(int x,int y)
        {
            To[cnt]=y;
            nxt[cnt]=head[x];
            head[x]=cnt;
            cnt++;
        }
    }W;
     
    int DFN[8005],LOW[8005],stack[8005],top,nt,vis[8005],cot;
    int clo[8005]; 
    void tarjan(int x)
    {
        DFN[x]=LOW[x]=++nt;
        stack[++top]=x;
        vis[x]=1;
            for(int i=W.head[x];i!=-1;i=W.nxt[i]){
                if(!DFN[W.To[i]]){
                    tarjan(W.To[i]);
                    LOW[x]=min(LOW[x],LOW[W.To[i]]);
                }
                else if(vis[W.To[i]])LOW[x]=min(LOW[x],DFN[W.To[i]]);
            }
        if(DFN[x]==LOW[x]){
            cot++;
            while(stack[top]!=x)clo[stack[top]]=cot,vis[stack[top--]]=0;
            clo[stack[top]]=cot,vis[stack[top--]]=0;
        }
    }
     
    int main()
    {
        //freopen("x.txt","r",stdin);
        scanf("%d
    ",&N);
        W.clear();
        register int i,j;
        int now=0;
            for(i=1;i<=N;i++){
                cin>>S1>>S2;
                if(!MP[S1])MP[S1]=++now;
                if(!MP[S2])MP[S2]=MP[S1]+N;
                W.add(MP[S1],MP[S2]);
            }
        scanf("%d
    ",&M);
            for(i=1;i<=M;i++){
                cin>>S1>>S2;
                W.add(MP[S2],MP[S1]);
            }
            for(i=1;i<=N*2;i++){
                if(!DFN[i])tarjan(i);
            }
            for(i=1;i<=N;i++){
                if(clo[i]==clo[i+N])puts("Unsafe");
                else puts("Safe");
            }
        return 0;
    }
  • 相关阅读:
    用C#设置系统时间和本地时间
    在ASP.NET中使用Session常见问题集锦 收藏
    C#开源资源大汇总(2)
    漫谈ASP.NET设计中的性能优化问题
    比较著名的.net技术论坛名称(含国外的)
    在ASP.NET 2.0中,一个ASP.NET页面的生命周期
    DataGrid技巧大集合(转载)
    Silverlight经典教程书籍汇总
    Asp.Net细节性问题技巧精萃
    C#开源资源大汇总(1)
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8557301.html
Copyright © 2011-2022 走看看