zoukankan      html  css  js  c++  java
  • POJ 1904

    题意略。

    思路:

    我们按大臣给出的完美匹配,将王子向少女和少女向王子连一条双向边,这样,这张图里就出现了n个强连通分量。如果将王子记为x,将少女记为y,则:

    如果xi 不再选择 yi,而是选择了 yj ,为了保持匹配不变,xj需要选择yi,或者 xj 选择了 yk ,最终 xk 选择了 yi。不论如何,这都是一个环,此时你会发现

    多个小连通分量合成了一个大联通分量,也就是说,当前王子只要选择自己连通分量之内喜欢的姑娘,通过两点之间互达的性质,我们总能给他的原配找

    到别的王子。

    本题输入可能有点大,使用输入输出外挂比较合适。

    详见代码:

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    using namespace std;
    const int maxn = 4005;
    
    int V,n;
    vector<int> graph[maxn];
    vector<int> rgraph[maxn];
    vector<int> store[maxn];
    vector<int> vs;
    bool used[maxn];
    int component[maxn];
    
    int scan(){
        int res = 0,ch,flag = 0;
        if((ch = getchar()) == '-') flag = 1;
        else if(ch >= '0' && ch <= '9') res = ch - '0';
        while((ch = getchar()) >= '0' && ch <= '9')
            res = res * 10 + ch - '0';
        return flag ? -res : res;
    }
    void out(int a){
        if(a > 9) out(a / 10);
        putchar(a % 10 + '0');
    }
    void add_e(int from,int to){
        graph[from].push_back(to);
        rgraph[to].push_back(from);
    }
    void dfs(int v){
        used[v] = true;
        for(int i = 0;i < graph[v].size();++i){
            int to = graph[v][i];
            if(used[to]) continue;
            dfs(to);
        }
        vs.push_back(v);
    }
    void rdfs(int v,int k){
        used[v] = true;
        component[v] = k;
        for(int i = 0;i < rgraph[v].size();++i){
            int to = rgraph[v][i];
            if(used[to]) continue;
            rdfs(to,k);
        }
    }
    int scc(){
        memset(used,false,sizeof(used));
        vs.clear();
        for(int v = 1;v <= V;++v){
            if(used[v]) continue;
            dfs(v);
        }
        memset(used,false,sizeof(used));
        int k = 0;
        for(int i = vs.size() - 1;i >= 0;--i){
            if(!used[vs[i]]) rdfs(vs[i],k++);
        }
        return k;
    }
    
    int main(){
        n = scan();
        for(int i = 0;i < maxn;++i){
            graph[i].clear();
            rgraph[i].clear();
            store[i].clear();
        }
        memset(component,0,sizeof(component));
        for(int i = 1;i <= n;++i){
            int ki = scan();
            int v;
            for(int j = 0;j < ki;++j){
                v = scan();
                v += n;
                add_e(i,v);
            }
        }
        int girl;
        for(int i = 1;i <= n;++i){
            girl = scan();
            girl += n;
            add_e(girl,i);
        }
        V = n<<1;
        int numb = scc();
        for(int i = 1;i <= n;++i){
            int part1 = component[i];
            for(int j = 0;j < graph[i].size();++j){
                int to = graph[i][j];
                int part2 = component[to];
                if(part2 == part1)
                    store[i].push_back(to - n);
            }
            sort(store[i].begin(),store[i].end());
        }
        for(int i = 1;i <= n;++i){
            out(store[i].size());
            for(int j = 0;j < store[i].size();++j){
                putchar(' ');
                out(store[i][j]);
            }
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    hdoj5327【前缀和思想】
    codeforces 611C
    codeforces 632C
    poj1163 【记忆化搜索·水】
    2016 Multi-University Training Contest 2 A Acperience
    细剖最短路【闲谈,权当是饭后杂文】
    poj1724【最短路】
    [YY题]HDOJ5288 OO’s Sequence
    Codeforces Round #363 (Div. 2) C. Vacations
    POJ2105【进制转化】
  • 原文地址:https://www.cnblogs.com/tiberius/p/9335459.html
Copyright © 2011-2022 走看看