zoukankan      html  css  js  c++  java
  • POJ-1904-King‘s Quest

    链接:

    https://vjudge.net/problem/POJ-1904

    题意:

    Once upon a time there lived a king and he had N sons. And there were N beautiful girls in the kingdom and the king knew about each of his sons which of those girls he did like. The sons of the king were young and light-headed, so it was possible for one son to like several girls.

    So the king asked his wizard to find for each of his sons the girl he liked, so that he could marry her. And the king's wizard did it -- for each son the girl that he could marry was chosen, so that he liked this girl and, of course, each beautiful girl had to marry only one of the king's sons.

    However, the king looked at the list and said: "I like the list you have made, but I am not completely satisfied. For each son I would like to know all the girls that he can marry. Of course, after he marries any of those girls, for each other son you must still be able to choose the girl he likes to marry."

    The problem the king wanted the wizard to solve had become too hard for him. You must save wizard's head by solving this problem.

    思路:

    对王子喜欢的连一条边,再通过最后给的结婚关系,从女孩到王子连一条边。
    再求强连通,再一个强连通内的王子和女孩肯定可以结婚。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <memory.h>
    #include <queue>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <math.h>
    #include <stack>
    using namespace std;
    const int MAXN = 4e3+10;
    
    vector<int> G[MAXN];
    int Dfn[MAXN], Low[MAXN];
    int Vis[MAXN], Dis[MAXN];
    int Fa[MAXN];
    stack<int> St;
    int n, cnt;
    int times;
    
    void Tarjan(int x)
    {
        Dfn[x] = Low[x] = ++times;
        Vis[x] = 1;
        St.push(x);
        for (int i = 0;i < G[x].size();i++)
        {
            int nextnode = G[x][i];
            if (Dfn[nextnode] == 0)
            {
                Tarjan(nextnode);
                Low[x] = min(Low[x], Low[nextnode]);
            }
            else if (Vis[nextnode])
                Low[x] = min(Low[x], Dfn[nextnode]);
        }
        if (Low[x] == Dfn[x])
        {
            cnt++;
            while (St.top() != x)
            {
                Fa[St.top()] = cnt;
                Vis[St.top()] = 0;
                St.pop();
            }
            Fa[St.top()] = cnt;
            Vis[St.top()] = 0;
            St.pop();
        }
    }
    
    int main()
    {
        scanf("%d", &n);
        for (int i = 1;i <= n;i++)
        {
            int num, g;
            scanf("%d", &num);
            while (num--)
            {
                scanf("%d", &g);
                G[i].push_back(n+g);
            }
        }
        int g;
        for (int i = 1;i <= n;i++)
        {
            scanf("%d", &g);
            G[n+g].push_back(i);
        }
        for (int i = 1;i <= 2*n;i++)
        {
            if (Dfn[i] == 0)
                Tarjan(i);
        }
        for (int i = 1;i <= n;i++)
        {
            set<int> st;
            for (int j = 0;j < G[i].size();j++)
            {
                int node = G[i][j];
                if (Fa[i] == Fa[node])
                    st.insert(node-n);
            }
            printf("%d", st.size());
            set<int>::iterator it = st.begin();
            while (it != st.end())
            {
                printf(" %d", *it);
                it++;
            }
            printf("
    ");
        }
    
        return 0;
    }
    
  • 相关阅读:
    利用存储过程生成随机数,并用其它存储过程调用此过程
    dataGridView中的数据操作
    listView绑定数据
    我的简易 数据存取器 的封装
    dataGridView 控件的简单绑定
    文件写入写出的封装
    Button1.Attributes.Add()方法小结
    自定义分页栏
    安迪的找工作日志——9.12笔试(优酷土豆)问题及解答
    安迪的找工作日志——9.13在教四四楼墙上看到的
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11176365.html
Copyright © 2011-2022 走看看