zoukankan      html  css  js  c++  java
  • HDU 3081 最大流+并查集

    题意:有n个男生和n个女生,玩结婚游戏,由女生选择男生;女生可以选择不会和她吵架的男生以及不会和她闺蜜吵架的男生,闺蜜的闺蜜也是闺蜜。问你最多可以进行多少轮,每一轮每个女生只能选择一个之前她没选过的男生。

    思路:显然最少进行0轮,最多进行n轮,所以我们可以对轮数进行二分;源点到女生连一条容量为轮数的边,女生到她可选择的男生之间连一条容量为1的边,男生到汇点同样连一条容量为轮数的边,然后跑最大流判断是否满流。找到最大的轮数。要注意的是,每次跑最大流的时候都要重新建图。至于闺蜜的问题用一个并查集就可以了。

    代码:

      1 #include<stdio.h> 
      2 #include<string.h>
      3 #define min(x,y) (x)<(y)?(x):(y)
      4 const int N=222,M=N*N,INF=0x3f3f3f3f;
      5 int n,l,r,s,t;
      6 int c[N][N],tmpc[N][N];
      7 int fa[N];
      8 int h[N],gap[N];
      9 int find(int a)
     10 {
     11     if(fa[a]!=a)    return fa[a]=find(fa[a]);
     12     return a;
     13 }
     14 void union_(int a,int b)
     15 {
     16     a=find(a),b=find(b);
     17     if(a!=b)    fa[a]=b;
     18 }
     19 int dfs(int u,int flow)
     20 {
     21     if(u==t)    return flow;
     22     int a,v,cc=flow,minh=t;
     23     for(v=1;v<=t;v++)
     24     {
     25         if(c[u][v])
     26         {
     27             if(h[v]==h[u]-1)
     28             {
     29                 a=min(c[u][v],flow);
     30                 a=dfs(v,a);
     31                 c[u][v]-=a;
     32                 cc-=a;
     33                 c[v][u]+=a;
     34                 if(h[s]>t)    return flow-cc;
     35                 if(!cc)    break;
     36             }
     37             minh=min(minh,h[v]);
     38         }
     39     }
     40     if(cc==flow)
     41     {
     42         if(--gap[h[u]]==0)    h[s]=t+1;
     43         ++gap[h[u]=minh+1];
     44     }
     45     return flow-cc;
     46 }
     47 int isap()
     48 {
     49     memset(gap,0,sizeof(gap));
     50     memset(h,0,sizeof(h));
     51     int ans=0;gap[0]=t+1;
     52     while(h[s]<=t)
     53         ans+=dfs(s,INF);
     54     return ans;
     55 }
     56 int bin()
     57 {
     58     int l=0,r=n,mid,i,j,ans;
     59     while(l<=r)
     60     {
     61         mid=(l+r)>>1;
     62         for(i=1;i<=n;i++)
     63             c[s][i]=mid,c[i+n][t]=mid;
     64         for(i=1;i<=n;i++)
     65             for(j=n+1;j<=n+n;j++)
     66                 c[i][j]=tmpc[i][j];
     67         if(mid*n==isap())
     68         {
     69             ans=mid;
     70             l=mid+1;
     71         }
     72         else
     73             r=mid-1;
     74     }
     75     return ans;
     76 }
     77 int main()
     78 {
     79     int T,m,k,i,j,x,y;
     80     scanf("%d",&T);
     81     while(T--)
     82     {
     83         scanf("%d%d%d",&n,&m,&k);
     84         memset(c,0,sizeof(c));
     85         s=0,t=n*2+1;
     86         for(i=1;i<=n;i++)
     87             fa[i]=i;
     88         while(m--)
     89         {
     90             scanf("%d%d",&x,&y);
     91             c[x][y+n]=1;
     92         }
     93         while(k--)
     94         {
     95             scanf("%d%d",&x,&y);
     96             union_(x,y);
     97             for(i=1;i<=n;i++)
     98             {
     99                 if(find(i)==find(x))
    100                 {
    101                     for(j=n+1;j<=n+n;j++)
    102                     {
    103                         if(c[i][j]&&!c[x][j])
    104                             c[x][j]=1;
    105                     }
    106                 }
    107                 if(find(i)==find(y))
    108                 {
    109                     for(j=n+1;j<=n+n;j++)
    110                     {
    111                         if(c[i][j]&&!c[y][j])
    112                             c[y][j]=1;
    113                     }
    114                 }
    115             }
    116         }
    117         for(i=1;i<=n;i++)    for(j=n+1;j<=n+n;j++)    tmpc[i][j]=c[i][j];
    118         printf("%d
    ",bin());
    119     }
    120     return 0;
    121 }
    View Code
  • 相关阅读:
    ssh-keygen Linux 免密登录
    hostnamectl 修改 CentOS7 主机名
    微信公众平台开发—24点游戏
    微信公众平台开发—起步
    java的静态代理和动态代理(jdk、cglib)
    UEditor上传图片到七牛云储存(java)
    第四十篇-private,public,protected的区别
    第七篇--ubuntu18.04下面特殊符号
    6. 计算器界面
    第六篇--Ubuntu画图软件
  • 原文地址:https://www.cnblogs.com/L-King/p/5349653.html
Copyright © 2011-2022 走看看