• hdu Marriage Match II


      1 /*
      2 hdu       Marriage Match II
      3 题意:n个女孩有n个不是敌对的男孩 其中f对女生彼此是朋友 可以传递的(暗示并查集)
      4       每个女生i也可以和她女朋友j的不敌对的男朋友b配对  每一轮匹配都可以一一对应不重复
      5       问最多可以有几轮M(最大最小 暗示 二分匹配)。
      6 思路:最大流 建图 totals=n+n+2;end=2n+1;
      7       start和女生节点建边 addedge(start,i,M);//边容量为M
      8        男生汇聚终点 addedge(i+n,end,M);//边流量为M
      9        每个女生也可以和她女朋友的不敌对的男朋友配对 
     10        建边addedge(i,b+n,1);//一男一女容量1
     11 结果:M和最大流t关系为 M==t*n 这个为判断条件 二分求出最大M
     12 */
     13 #include <iostream>
     14 #include<cstdio>
     15 #include<cstring>
     16 #include<vector>
     17 #include<queue>
     18 #include<algorithm>
     19 using namespace std;
     20 #define min(a,b) ((a)<(b))?(a):(b)
     21 #define max(a,b) ((a)>(b))?(a):(b)
     22 #define MAXN 6005//尽量开大点
     23 #define MAXM  100002 //M取N的平方倍或者N*9
     24 #define INF 0x3f3f3f3f
     25 int m,n;
     26 int start,end;
     27 struct node
     28 {
     29     int n;//点编号
     30     int w;//点权
     31 }Node[MAXM];//n变m
     32 
     33 //链式前向星
     34 struct enode
     35 {
     36     int t;
     37     int w;                //权值
     38     int c;                //流量
     39 //  int cost;
     40 //    int pre;            //前向指针
     41     int next;
     42 };
     43 
     44     struct enode e[MAXM];
     45     int box[MAXN],ecnt;
     46     //int etail[MAXN];        //尾部
     47     void init()
     48     {
     49         ecnt=0;
     50         memset(box,-1,sizeof(box));
     51     //    memset(etail,-1,sizeof(etail));        //初始化尾部
     52     }
     53     void add(int s,int t)
     54     {
     55          e[ecnt].t=t;
     56          e[ecnt].next=box[s];
     57          box[s]=ecnt++;
     58     }
     59     void addedge(int f,int t,int c)            //流量重载
     60     {
     61         e[ecnt].next=box[f];
     62         e[ecnt].t=t;
     63         e[ecnt].c=c;
     64         box[f]=ecnt++;
     65         e[ecnt].next=box[t];
     66         e[ecnt].t=f;
     67         e[ecnt].c=0;
     68         box[t]=ecnt++;
     69     }
     70 int sap(int s,int t,int N)//最大流问题
     71 {
     72     int gap[MAXN],lvl[MAXN],cur[MAXN],pre[MAXN];
     73     int curflow,ans=0,u,tmp,neck,i;
     74     memset(lvl,0,sizeof(lvl));
     75     memset(gap,0,sizeof(gap));
     76     memset(pre,-1,sizeof(pre));
     77     for(i=0;i<N;i++)
     78         cur[i]=box[i];
     79     gap[0]=N;
     80     u=s;
     81     while(lvl[s]<N)
     82     {
     83         if(u==t)
     84         {
     85             curflow=INF;
     86             for(i=s;i!=t;i=e[cur[i]].t)
     87             {
     88                 if(curflow>e[cur[i]].c)
     89                 {
     90                     neck=i;
     91                     curflow=e[cur[i]].c;
     92                 }
     93             }
     94             for(i=s;i!=t;i=e[cur[i]].t)
     95             {
     96                 tmp=cur[i];
     97                 e[tmp].c-=curflow;
     98                 e[tmp^1].c+=curflow;
     99             }
    100             ans+=curflow;
    101             u=neck;
    102         }
    103         for(i=cur[u];i!=-1;i=e[i].next)
    104             if(e[i].c && lvl[u]==lvl[e[i].t]+1)
    105                 break;
    106         if(i!=-1)
    107         {
    108             cur[u]=i;
    109             pre[e[i].t]=u;
    110             u=e[i].t;
    111         }
    112         else
    113         {
    114             if(--gap[lvl[u]]==0)
    115                 break;
    116              cur[u]=box[u];
    117             for(tmp=N,i=box[u];i!=-1;i=e[i].next)
    118                 if(e[i].c)
    119                     tmp=min(tmp,lvl[e[i].t]);
    120             lvl[u]=tmp+1;
    121             gap[lvl[u]]++;
    122             if(u!=s)
    123                 u=pre[u];
    124         }
    125     }
    126     return ans;
    127 }
    128 struct S
    129 {
    130     int a,b;
    131 };
    132 S p[15000];
    133 
    134 struct SS
    135 {
    136     int a,b;
    137     int f[MAXN];
    138     void init()
    139     {
    140         for(int i=1;i<=n;i++)f[i]=i;
    141     }
    142     int find(int x)
    143     {
    144         int r=x;
    145         while(f[r]!=r)
    146         r=f[r];
    147         f[x]=r;
    148         return f[x];
    149     }
    150     void uni(int x,int y )
    151     {
    152         x=find(x);
    153         y=find(y);
    154         if(x!=y)
    155         f[x]=y;
    156     }
    157 };
    158 SS  s;
    159 void build(int M)
    160 {
    161     int i,j;
    162     init();
    163     int _f[200][200];
    164     memset(_f,0,sizeof(_f));
    165     for(i=1;i<=n;i++)
    166     {
    167         addedge(start,i,M);
    168         addedge(i+n,end,M);
    169     }
    170     for(i=1;i<=m;i++)
    171     {
    172         int a=p[i].a,b=p[i].b;
    173         for(j=1;j<=n;j++)
    174         {
    175             if(s.f[a]==s.f[j]&&!_f[j][b])
    176             {
    177                 addedge(j,b+n,1);
    178                 _f[j][b]=1;
    179             }
    180         }
    181     }
    182 }
    183 int main()
    184 {
    185      int a,b;
    186      int i,j,f;
    187      int T;
    188 
    189 
    190      scanf("%d",&T);
    191      while(T--)
    192      {
    193          scanf("%d%d%d",&n,&m,&f);
    194          init();
    195          start=0;end=2*n+1;
    196          for(i=1;i<=m;i++)
    197          {
    198             scanf("%d%d",&p[i].a,&p[i].b);
    199          }
    200          s.init();
    201          for(i=1;i<=f;i++)
    202          {
    203              scanf("%d%d",&a,&b);
    204              s.uni(a,b);
    205          }
    206          for(i=1;i<=n;i++)
    207          s.f[i]=s.find(i);
    208          int L=0,R=n,ans=0;
    209          while(L<=R)
    210          {
    211              int M=(L+R)/2;
    212              build(M);
    213              if(sap(start,end,end+1)==M*n)
    214              {
    215                  L=M+1;
    216                  ans=M;
    217              }else R=M-1;
    218          }
    219          printf("%d\n",ans);
    220      }
    221 
    222     return 0;
    223 }
    224 /*
    225 1
    226 4 5 2
    227 1 1
    228 2 3
    229 3 2
    230 4 2
    231 4 4
    232 1 4
    233 2 3
    234 
    235 
    236 
    237 Sample Output
    238 
    239 2
    240 
    241 */
  • 相关阅读:
    第二题
    第一题
    biancheng
    用泰勒展开式计算sin
    矩阵求和
    1
    ti
    实验10
    实验9
    实验8
  • 原文地址:https://www.cnblogs.com/someonelikeyou/p/3041310.html
Copyright © 2020-2023  润新知