zoukankan      html  css  js  c++  java
  • poj 2289 二分+多重匹配

    最大值最小的一个常用方法是二分。二分“the size of the largest group”然后每次判断最大匹配数是否为人数即可。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cctype>
      5 using namespace std;
      6 
      7 const int X = 1000;
      8 const int Y = 500;
      9 int head[X];
     10 int cnt[Y];
     11 int mark[Y][X];
     12 bool visit[Y];
     13 int n, m, e, sz;
     14 
     15 void init()
     16 {
     17     e = 0;
     18     memset( head, -1, sizeof(head) );
     19 }
     20 
     21 struct Edge 
     22 {
     23     int v, next;
     24 } edge[X * Y];
     25 
     26 void addEdge( int u, int v )
     27 {
     28     edge[e].v = v;
     29     edge[e].next = head[u];
     30     head[u] = e++;
     31 }
     32 
     33 int dfs( int u )
     34 {
     35     for ( int i = head[u]; i != -1; i = edge[i].next )
     36     {
     37         int v = edge[i].v;
     38         if ( !visit[v] )
     39         {
     40             visit[v] = 1;
     41             if ( cnt[v] < sz )
     42             {
     43                 mark[v][cnt[v]++] = u;
     44                 return 1;
     45             }
     46             else
     47             {
     48                 for ( int j = 0; j < cnt[v]; j++ )
     49                 {
     50                     if ( dfs( mark[v][j] ) )
     51                     {
     52                         mark[v][j] = u;
     53                         return 1;
     54                     }
     55                 }
     56             }
     57         }
     58     }
     59     return 0;
     60 }
     61 
     62 bool hungary()
     63 {
     64     memset( cnt, 0, sizeof(cnt) );
     65     for ( int i = 0; i < n; i++ )
     66     {
     67         memset( visit, 0, sizeof(visit) );
     68         if ( !dfs(i) ) return false;
     69     }
     70     return true;
     71 }
     72 
     73 const int L = 501;
     74 char list[L];
     75 
     76 int main ()
     77 {
     78     while ( scanf("%d%d", &n, &m) != EOF )
     79     {
     80         if ( n == 0 && m == 0 ) break;
     81         init();
     82         getchar();
     83         for ( int i = 0; i < n; i++ )
     84         {
     85             gets(list);
     86             int len = strlen(list);
     87             int j = 0, ret;
     88             while ( 1 )
     89             {
     90                 while ( !isdigit(list[j]) ) j++;
     91                 ret = 0;
     92                 while ( isdigit(list[j]) )
     93                 {
     94                     ret = ret * 10 + list[j] - '0';
     95                     j++;
     96                 }
     97                 addEdge( i, ret );
     98                 if ( j == len ) break;
     99             }
    100         }
    101         int lb = 1, ub = n;
    102         while ( lb < ub )
    103         {
    104             sz = ( lb + ub ) >> 1;
    105             if ( hungary() )
    106             {
    107                 ub = sz;
    108             }
    109             else
    110             {
    111                 lb = sz + 1;
    112             }
    113         }
    114         printf("%d
    ", lb);
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    Linux 高性能server编程——高级I/O函数
    中国儿童移动游戏市场解读 潜力巨大有待开发
    HDU 2152 Fruit (母函数)
    Currying vs Partial Application
    我的最爱Lambda演算——开篇
    函数式编程-数据结构+算法
    高阶函数 、高阶类型
    高阶函数-哈哈
    备份-泛函编程(23)-泛函数据类型-Monad
    高阶函数
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4752236.html
Copyright © 2011-2022 走看看