zoukankan      html  css  js  c++  java
  • hust 1024 dance party

    题目描述

    You are organizing a dance party. The party will be attended by n boys and n girls. There will be several rounds of dancing. In each round, you divide the guests into n dancing pairs. Each guest must be in exactly one pair, and each pair must contain one boy and one girl. Each boy must dance with a different girl in every round. Some boys and girls like each other and some do not. During the party, each boy agrees to dance with at most k girls he doesn't like. Similarly, each girl agrees to dance with at most k boys she doesn't like. You are given the each pairs of boys and girls who agree to dance with each other .Find out the maximum number of rounds you can organize.

    输入

    The first line contains a integer t,which means there are t cases followed. For each case,the first line contain three integer n,m,k ,which means there are n boys and n girls attending the party and m pairs of boys and girls who agree to dance with each other,and each boy or girl agrees to dance with at most k girls or boys he or she doesn't like.At last ,there are m lines with two integers a,b which means boy a and girl b agree to dance with each other. (0<n<=100,0<m<=n*n,0<k<100,0<a,b<=n)

    输出

    The output cotains only one integer which means the maximum number of rounds you can organize.

    样例输入

    2
    2 4 0
    1 1
    2 2
    2 1
    1 2
    3 7 0
    1 1
    1 2
    1 3
    2 1
    2 2
    3 1
    3 3

    样例输出

    2
    2
    这个题好久就看到了,但是由于一直不知道怎么做,故没有做,不过,最近在刷网络流的题目,于是就拿这个题来看看,原来真的是网络流的题目啊,拆边,每个男孩和女孩都拆成三条边,对于每个boy,拆成boy,boy1,boy2,然后boy到boy1连一条边,容量为inf,boy到boy2连一条边,容量为k,女孩也是;然后就是,如果boy和girl可以跳就boy1和girl1连一条边,容量为1,若不跳,则boy2,girl2连一条边,容量为1,然后在枚举答案,从最大的开始枚举,找到就是,不用再继续找,假设当前枚举到ans,则源点向每个boy连一条容量为ans的边,每个girl向汇点连一条容量为ans的边,这样就算一下最大流,当最大流为满流的时候,就满足条件,就得到答案,用Dinic算法,在最坏的情况下时间复杂度为O(n^4*n),不过数据没有那么吓人,在2s内就能出解,具体看程序
    #include<map>
    #include<set>
    #include<stack>
    #include<queue>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define  inf 0x0f0f0f0f
    
    using namespace std;
    
    const double pi=acos(-1.0);
    const double eps=1e-8;
    typedef pair<int,int>pii;
    
    const int maxn=10000+10;
    
    struct Edge
    {
        int from,to,cap,flow;
    };
    
    int n,m,s,t;
    vector<Edge>edges;
    vector<int>G[maxn];
    int d[maxn],cur[maxn];
    bool vis[maxn];
    
    void AddEdge(int from,int to,int cap)
    {
        Edge temp;
        temp.cap=cap; temp.flow=0; temp.from=from; temp.to=to;
        edges.push_back(temp);
        temp.cap=0; temp.flow=0; temp.from=to; temp.to=from;
        edges.push_back(temp);
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    
    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int>Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!Q.empty())
        {
            int x=Q.front();Q.pop();
            for (int i=0;i<G[x].size();i++)
            {
                Edge& e=edges[G[x][i]];
                if (!vis[e.to] && e.cap>e.flow)
                {
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    
    int DFS(int x,int a)
    {
        if (x==t || a==0) return a;
        int flow=0,f;
        for (int i=cur[x];i<G[x].size();i++)
        {
            Edge& e=edges[G[x][i]];
            if (d[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if (a==0) break;
            }
        }
        return flow;
    }
    
    int Dinic()
    {
        int flow=0;
        while (BFS())
        {
            memset(cur,0,sizeof(cur));
            flow+=DFS(s,inf);
        }
        return flow;
    }
    
    void init()
    {
        for (int i=0;i<=maxn;i++) G[i].clear();
        edges.clear();
    }
    int parr[101][101];
    int find(int N,int k)
    {
        int ans=N;
        while(1)
        {
            init();
            for (int i=1;i<=N;i++)
            {
                int boy=(i-1)*3+1;
                AddEdge(boy,boy+1,inf);
                AddEdge(boy,boy+2,k);
                int girl=(i-1)*3+1+3*N;
                AddEdge(girl+1,girl,inf);
                AddEdge(girl+2,girl,k);
            }
            for (int i=1;i<=N;i++)
            for (int j=1;j<=N;j++)
            {
                if (parr[i][j]==0)
                {
                    int boy=(i-1)*3+1;
                    int girl=(j-1)*3+1+3*N;
                    AddEdge(boy+2,girl+2,1);
                }
                else
                {
                    int boy=(i-1)*3+1;
                    int girl=(j-1)*3+1+3*N;
                    AddEdge(boy+1,girl+1,1);
                }
            }
            for (int i=1;i<=N;i++)
            {
                int boy=(i-1)*3+1;
                int girl=boy+3*N;
                AddEdge(s,boy,ans);
                AddEdge(girl,t,ans);
            }
            if (Dinic()==N*ans) break;
            else ans--;
        }
        return ans;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T,N,M,k;
        scanf("%d",&T);
        while (T--)
        {
            init();
            scanf("%d%d%d",&N,&M,&k);
            s=0;t=6*N+1;
    
            memset(parr,0,sizeof(parr));
            for (int i=1;i<=M;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                parr[x][y]=1;
            }
    
            printf("%d
    ",find(N,k));
        }
        //fclose(stdin);
        return 0;
    }
    至少做到我努力了
  • 相关阅读:
    kafka与Rocketmq的区别
    CentOS7 安装特定版本的Docker brady
    Postgresql Error : must be superuser to alter superusers.
    php 用redis实现购物车底层代码
    查找文件夹中包含某字符的文件和行数
    utabs 下划线在微信端不出来
    PHP的生成器yield处理大量数据杠杠
    direction: rtl;
    强制html以https格式访问引入文件
    uviewui 引入 easycom 不用每个页面都引入
  • 原文地址:https://www.cnblogs.com/chensunrise/p/3704581.html
Copyright © 2011-2022 走看看