zoukankan      html  css  js  c++  java
  • N

    题目大意:有一些男孩和女孩玩一个游戏,每个女孩都可以挑一个男孩来进行这个游戏(所有人都要参加),女孩只会挑选她喜欢的男孩,并且她们认为她们朋友喜欢的男孩她们也是喜欢的(朋友的男朋友也是我的男朋友???),而且她们遵循朋友的朋友也是朋友的原则,问她们最多可以玩几轮游戏(每轮要选择的人不能和以前选择的相同)。
     
    分析:朋友关系很明显可以使用并查集找出来每个女孩可以连接的男孩,因为要求的是最多能进行多少轮游戏,也就是在这x轮游戏中每个女孩换了x不同的男孩,每个男孩也换了x个不同的女孩,如果源点和女孩相连,汇点和男孩相连,那么流量一定是N*x,可以使用二分来查找最大的x。
    下面是AC代码。
    =========================================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<stack>
    #include<vector>
    using namespace std;
    
    const int MAXN = 207;
    const int oo = 1e9+7;
    
    int G[MAXN][MAXN], Layer[MAXN], N, M;
    int girl[MAXN*MAXN], boy[MAXN*MAXN], father[MAXN];
    vector<int>love[MAXN];
    
    int Find(int x)
    {
        if(father[x] != x)
            father[x] = Find(father[x]);
        return father[x];
    }
    void InIt()
    {
        for(int i=1; i<=N; i++)
        {
            father[i] = i;
            love[i].clear();
        }
    }
    void BuidGraph(int flow, int start, int End)
    {
        memset(G, 0, sizeof(G));
    
        for(int i=1; i<=N; i++)
        {///源点和女孩相连,汇点和男孩相连,流量是flow
            G[start][i] = flow;
            G[i+N][End] = flow;
    
            int u = Find(i);///注意别用father[i]
            int len = love[u].size();
    
            for(int j=0; j<len; j++)
            {///女孩和男孩之间的流量是1
                G[i][love[u][j]] = 1;
            }
        }
    }
    bool BFS(int start, int End)
    {
        memset(Layer, 0, sizeof(Layer));
        queue<int> Q;
        Q.push(start);
        Layer[start] = 1;
    
        while(Q.size())
        {
            int u = Q.front();Q.pop();
    
            if(u == End)return true;
    
            for(int v=1; v<=End; v++)
            {
                if(Layer[v]==false && G[u][v])
                {
                    Layer[v] = Layer[u] + 1;
                    Q.push(v);
                }
            }
        }
    
        return false;
    }
    int DFS(int u, int MaxFlow, int End)
    {
        if(u == End)return MaxFlow;
    
        int uflow = 0;
    
        for(int v=1; v<=End; v++)
        {
            if(Layer[v]==Layer[u]+1 && G[u][v])
            {
                int flow = min(MaxFlow-uflow, G[u][v]);
                flow = DFS(v, flow, End);
    
                G[u][v] -= flow;
                G[v][u] += flow;
                uflow += flow;
    
                if(uflow == MaxFlow)
                    break;
            }
        }
    
        if(uflow == 0)
            Layer[u] = 0;
        return uflow;
    }
    int Dinic(int start, int End)
    {
        int MaxFlow = 0;
    
        while(BFS(start, End) == true)
            MaxFlow += DFS(start, oo, End);
    
        return MaxFlow;
    }
    
    int main()
    {
        int T;
    
        scanf("%d", &T);
    
        while(T--)
        {
            int i, F, u, v;
    
            scanf("%d%d%d", &N, &M, &F);
    
            InIt();
    
            for(i=1; i<=M; i++)
                scanf("%d%d", &girl[i], &boy[i]);
            for(i=1; i<=F; i++)
            {///用并查集合并朋友关系
                scanf("%d%d", &u, &v);
                u = Find(u);
                v = Find(v);
    
                if(u != v)
                    father[u] = v;
            }
    
            for(i=1; i<=M; i++)
            {///把相同的朋友的男朋友全部都连接到根节点上,男生的区间N~2*N
                u = Find(girl[i]);
                love[u].push_back(boy[i]+N);
            }
    
            int start=N*2+1, End = start+1;
            int left = 0, right = N, ans=0;
    
            while(left <= right)
            {
                int Mid = (left+right)>>1;
    
                BuidGraph(Mid, start, End);
                int MaxFlow = Dinic(start, End);
    
                if(MaxFlow == Mid*N)
                {
                    left = Mid + 1;
                    ans = Mid;
                }
                else
                    right = Mid - 1;
            }
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    《python编程从入门到实践》变量和简单数据类型
    《初学python》
    centos7 关闭防火墙
    记几个学习资源
    servlet-api.jar
    spring 对Map的一种扩展 MultiValueMap
    CPU飚高问题解决
    聊聊数据库优化
    netty的核心组件
    【转】 一个著名的日志系统是怎么设计出来的?
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4728131.html
Copyright © 2011-2022 走看看