zoukankan      html  css  js  c++  java
  • HDU 4685 Prince and Princess

    强连通分量,看大神的题解才会写的....

    http://www.cnblogs.com/kuangbin/p/3261157.html

    数据量有点大,第一次Submit 2995ms过的,时限3000ms,差一点就TLE了。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    const int maxn = 2000 + 10;
    int N, M;
    vector<int>Cun[maxn];
    vector<int>G[maxn];
    vector<int>FG[maxn];
    int nx, ny, Time, Block;
    int g[maxn][maxn];
    int cx[maxn], cy[maxn];
    int mk[maxn];
    int flag[maxn], dfn[maxn], Belong[maxn];
    struct Point
    {
        int id, dfn;
    } point[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;
    }
    
    bool cmp(const Point&a, const Point&b)
    {
        return a.dfn>b.dfn;
    }
    
    int path(int u)
    {
        for (int v = 1; v <= ny; v++)
        {
            if (g[u][v] && !mk[v])
            {
                mk[v] = 1;
                if (cy[v] == -1 || path(cy[v]))
                {
                    cx[u] = v;
                    cy[v] = u;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int MaxMatch()
    {
        int res = 0;
        memset(cx, -1, sizeof(cx));
        memset(cy, -1, sizeof(cy));
        for (int i = 1; i <= nx; i++)
        {
            if (cx[i] == -1)
            {
                memset(mk, 0, sizeof(mk));
                res = res + path(i);
            }
        }
        return res;
    }
    
    void dfs(int now)
    {
        flag[now] = 1;
        for (int i = 0; i<G[now].size(); i++)
        if (!flag[G[now][i]])
            dfs(G[now][i]);
        Time++;
        dfn[now] = Time;
    }
    
    void Dfs(int now)
    {
        Belong[now] = Block;
        for (int i = 0; i<FG[now].size(); i++)
        if (!Belong[FG[now][i]])
            Dfs(FG[now][i]);
    }
    
    int main()
    {
        int CA;
        CA = Scan();
        for (int er = 1; er <= CA; er++){
            N = Scan();
            M = Scan();
            memset(flag, 0, sizeof(flag));
            memset(dfn, 0, sizeof(dfn));
            memset(Belong, 0, sizeof(Belong));
            Time = 0, Block = 0;
            for (int i = 0; i<maxn; i++) G[i].clear();
            for (int i = 0; i<maxn; i++) Cun[i].clear();
            for (int i = 0; i<maxn; i++) FG[i].clear();
            memset(g, 0, sizeof(g));
            nx = N, ny = M;
    
            for (int i = 1; i <= N; i++)
            {
                int ToT, To;
                ToT = Scan();
                while (ToT--)
                {
                    To = Scan();
                    Cun[i].push_back(To);
                    g[i][To] = 1;
                }
                sort(Cun[i].begin(), Cun[i].end());
            }
            int res = MaxMatch();
    
            memset(g, 0, sizeof(g));
            int A = M - res, B = N - res;//A表示虚拟王子数量,B表示虚拟妹子数量
            nx = N + A, ny = M + B;
            if (B>0)//王子有单身
            {
                for (int j = M + 1; j <= M + B; j++)
                for (int i = 1; i <= N; i++)
                {
                    g[i][j] = 1;
                    G[i].push_back(j + nx);
                    FG[j + nx].push_back(i);
                }
            }
            if (A>0)
            {
                for (int i = N + 1; i <= N + A; i++)
                for (int j = 1; j <= M; j++)
                {
                    g[i][j] = 1;
                    G[i].push_back(j + nx);
                    FG[j + nx].push_back(i);
                }
            }
            for (int i = 1; i <= N; i++)
            for (int j = 0; j<Cun[i].size(); j++)
            {
                g[i][Cun[i][j]] = 1;
                G[i].push_back(Cun[i][j] + nx);
                FG[Cun[i][j] + nx].push_back(i);
            }
            MaxMatch();
            for (int i = 1; i <= ny; i++)
            if (cy[i] != -1)
            {
                G[i + nx].push_back(cy[i]);
                FG[cy[i]].push_back(i + nx);
            }
    
            for (int i = 1; i <= nx + ny; i++) if (!dfn[i]) dfs(i);
            for (int i = 0; i<nx + ny; i++) point[i].id = i + 1, point[i].dfn = dfn[i + 1];
            sort(point, point + nx + ny, cmp);
            for (int i = 0; i<nx + ny; i++)
            if (!Belong[point[i].id])
                Block++, Dfs(point[i].id);
            int RT;
            int ans[maxn];
            printf("Case #%d:
    ", er);
            for (int i = 1; i <= N; i++)
            {
                RT = 0;
                for (int j = 0; j<Cun[i].size(); j++)
                {
                    if (Belong[i] == Belong[Cun[i][j] + nx])
                    {
                        ans[RT] = Cun[i][j];
                        RT++;
                    }
                }
                printf("%d", RT);
                for (int x = 0; x<RT; x++) printf(" %d", ans[x]);
                printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    Android 优雅的让Fragment监听返回键
    Android 去掉TabLayout下的阴影,AppBarLayout下的阴影
    mongodb.conf配置文件详解
    Ubuntu14.04下Mongodb的Java API编程实例(手动项目或者maven项目)
    Ubuntu14.04下初步使用MongoDB
    如何做到Ubuntu14.04下的mongdb远程访问?(图文详解)
    Ubuntu14.04下Mongodb(在线安装方式|apt-get)安装部署步骤(图文详解)(博主推荐)
    neo4j的配置文件(图文详解)
    Ubuntu14.04下Neo4j图数据库官网安装部署步骤(图文详解)(博主推荐)
    Ubuntu16.04下Neo4j图数据库官网安装部署步骤(图文详解)(博主推荐)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4776243.html
Copyright © 2011-2022 走看看