zoukankan      html  css  js  c++  java
  • poj 1904 King's Quest 强连通

    朴素的想法,对于每个王子,选取一个他喜欢的公主,然后对其他的进行一遍匹配看是否完备,不过时间复杂度太高,仔细想想这一过程,先看题目中给出的初始配对,王子甲本身配对的是公主甲,如果甲还可以选其他的公主比如说公主乙,那么如果王子乙可以选公主甲,那么结束,如果不能,则重复刚才的做法(其实就是匹配寻找增广路的过程),直到找到公主甲为止,这时发现,刚才走的其实是个环,所以说某王子可选的公主都跟他在一个强连通分量里。

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #include<stack>
    using namespace std;
    
    const int maxn = 12000 + 10;
    
    vector<int> G[maxn], G2[maxn];
    vector<int> S;
    vector<int> ans[maxn];
    int vis[maxn], sccno[maxn], scc_cnt;
    int n;
    int max(int a,int b)
    {
    	if(a>b) return a;
    	else return b;
    }
    void dfs1(int u)
    {
        if(vis[u]) return;
        vis[u] = 1;
        for(int i = 0; i < G[u].size(); i++) dfs1(G[u][i]);
        S.push_back(u);
    }
    
    void dfs2(int u)
    {
        if(sccno[u]) return;
        sccno[u] = scc_cnt;
        for(int i = 0; i < G2[u].size(); i++) dfs2(G2[u][i]);
    }
    
    void find_scc(int n)
    {
    	int i;
        scc_cnt = 0;
        S.clear();
        memset(sccno, 0, sizeof(sccno));
        memset(vis, 0, sizeof(vis));
        for(i = 0; i < n; i++) dfs1(i);
        for(i = n-1; i >= 0; i--)
        if(!sccno[S[i]]) { scc_cnt++; dfs2(S[i]); }
    }
    
    int main()
    {
        int i,j,k;
        int gir;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=0;i<=2*n;i++)
            {
                G[i].clear();
                G2[i].clear();
                ans[i].clear();
            }
            for(i=1;i<=n;i++)
            {
                scanf("%d",&k);
                for(j=1;j<=k;j++)
                {
                    scanf("%d",&gir);
                    G[i-1].push_back(gir+n-1);
                    G2[gir+n-1].push_back(i-1);
                }
            }
            for(i=1;i<=n;i++)
            {
                scanf("%d",&k);
                G[k-1+n].push_back(i-1);
                G2[i-1].push_back(k-1+n);
            }
            n=n*2;
            find_scc(n);
            n/=2;
            for(i=0;i<n;i++)
                for(j=0;j<G[i].size();j++)
                    if(sccno[i]==sccno[G[i][j]])
                        ans[i].push_back(G[i][j]);
            for(i=0;i<n;i++) sort(ans[i].begin(),ans[i].end());
            for(i=0;i<n;i++)
            {
                printf("%d",ans[i].size());
                for(j=0;j<ans[i].size();j++)
                    printf(" %d",ans[i][j]+1-n);
                printf("
    ");
            }
        }
        return 0;
    }
    


     

  • 相关阅读:
    HDU 1800 Flying to the Mars 字典树,STL中的map ,哈希树
    字典树 HDU 1075 What Are You Talking About
    字典树 HDU 1251 统计难题
    最小生成树prim算法 POJ2031
    POJ 1287 Networking 最小生成树
    次小生成树 POJ 2728
    最短路N题Tram SPFA
    poj2236 并查集
    POJ 1611并查集
    Number Sequence
  • 原文地址:https://www.cnblogs.com/vermouth/p/3832196.html
Copyright © 2011-2022 走看看