• 简单的二分匹配



    // HDU 2063
    1
    #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 int k,m,n;//m :女生人数 8 const int N=550; 9 vector<int>v[N]; 10 bool vis[N]; 11 int g[N];//g[i]=j i男 j女 12 bool match(int x){ 13 for(int j=0;j<v[x].size();j++)//男生 14 { int u=v[x][j]; 15 if(!vis[u]){ 16 vis[u]=1; 17 if(!g[u]||match(g[u])){ 18 //i男还没有匹配女生或者可以给该男生的原配女重新再找对应的 19 //男生 ,那么x(女)就可以匹配i(男)了 20 g[u]=x; 21 return 1; 22 } 23 } 24 } 25 return 0; 26 } 27 int main() 28 { 29 while(~scanf("%d",&k)&&k){ 30 31 scanf("%d%d",&m,&n); 32 int x,y; 33 memset(vis,0,sizeof(vis)); 34 memset(g,0,sizeof(g));//g,vis 都要清零 35 for(int i=1;i<=m;i++) 36 { 37 v[i].clear(); 38 } 39 for(int i=0;i<k;i++) 40 { 41 scanf("%d%d",&x,&y); 42 v[x].push_back(y); 43 } 44 int ans=0; 45 for(int i=1;i<=m;i++) 46 { 47 memset(vis,0,sizeof(vis)); 48 if(match(i)){ 49 ans++; 50 } 51 } 52 printf("%d ",ans); 53 } 54 return 0; 55 } 56 57 /* 58 || 1 || 2,判断到1就知道结果肯定是真,不再继续判断,返回1。 59 || 0 || 3, 判断到第一个就知道结果是真,不再继续判断,返回1。 60 || 0 || 0;一直判断到了最后一个,才知道结果为假,返回最后一个判断的0。 61 同理:&&运算符是只要一个为假就为假,所以它会从前往后一直找假的,返回最后一个判断的值。 62 */

     */ 1 // German Collegiate Programming Contest 2015

     2 //  B. Bounty Hunter II
    // n个顶点,m条边。问最少走几条路可以走完所有顶点
    // (不能走走过的顶点)
    /*

    DAG的最小路径覆盖是指找最小数目的互相不相交的有向路径,满足DAG的所有顶点都被覆盖.

    首先给出公式:DAG的最小路径覆盖数=DAG图中的节点数-相应二分图中的最大匹配数.

    */
     3 #include <iostream>
     4 #include <cstdio>
     5 #include <algorithm>
     6 #include <cstring>
     7 #include <vector>
     8 using namespace std;
     9 int  k,n;
    10 const int N=2550;//要大于2000
    11 vector<int>v[N];
    12 bool vis[N];
    13 int g[N];
    14 bool match(int x){
    15     for(int j=0;j<v[x].size();j++)
    16     {      int u=v[x][j];
    17         if(!vis[u]){
    18             vis[u]=1;
    19             if(g[u]==-1||match(g[u])){
    20                 
    21                 g[u]=x;
    22                 return 1;
    23             }    
    24         }
    25     }
    26     return 0;
    27 }
    28 int  main()
    29 {
    30         scanf("%d",&n);
    31         memset(g,-1,sizeof(g));
    32         int x;
    33         for(int i=0;i<n;i++)
    34         {
    35             scanf("%d",&k);
    36         for(int j=0;j<k;j++)
    37         {
    38             scanf("%d",&x);
    39             v[i].push_back(x+n);
    40         }
    41         }
    42         int ans=0;
    43         for(int  i=0;i<n;i++)
    44         {
    45             memset(vis,0,sizeof(vis));
    46             if(match(i)){
    47                 ans++;
    48             }
    49         }
    50     
    51         printf("%d
    ",n-ans);
    52     
    53     return 0;
    54 }

    DAG的最小路径覆盖是指找最小数目的互相不相交的有向路径,满足DAG的所有顶点都被覆盖.

    首先给出公式:DAG的最小路径覆盖数=DAG图中的节点数-相应二分图中的最大匹配数.

  • 相关阅读:
    Uploadify跨域上传原理
    C#中HttpClient使用注意:预热与长连接
    前端必读:浏览器内部工作原理
    从零开始学习jQuery
    ManualResetEvent 类的用法
    线程池用法的改进
    我的第一篇博客
    Es6新语法 let篇
    如何测试解析是否生效?
    主机记录和记录值(域名服务器绑定详解)
  • 原文地址:https://www.cnblogs.com/tingtin/p/9310629.html
Copyright © 2020-2023  润新知