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;
    }
  • 相关阅读:
    [Leetcode]847. Shortest Path Visiting All Nodes(BFS|DP)
    [Lintcode]Word Squares(DFS|字符串)
    [Lintcode]Inorder Successor in Binary Search Tree(DFS)
    xampp搭建discuz论坛
    Codeforces Round #459 (Div. 2):D. MADMAX(记忆化搜索+博弈论)
    网址备份
    java并发系列
    java创建多线程
    (转)深入理解Java内存模型之系列篇
    (转)Java并发编程:线程池的使用
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8557301.html
Copyright © 2011-2022 走看看