【01染色法判断二分匹配+匈牙利算法求最大匹配】HDU The Accomodation of Students

http://acm.hdu.edu.cn/showproblem.php?pid=2444

【DFS染色】

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<cmath>
  6 #include<algorithm>
  7
  8 using namespace std;
  9 const int maxn=2e2+3;
 10 const int maxm=maxn*maxn;
 11 struct edge
 12 {
 13     int to;
 14     int nxt;
 15 }e[maxm];
 16 int tot;
 17 int head[maxn];
 18 int col[maxn];
 19 bool vis[maxn];
 20 int link[maxn];
 21 void init()
 22 {
 23     tot=0;
 24     memset(head,-1,sizeof(head));
 25     memset(col,0,sizeof(col));
 26     memset(link,-1,sizeof(link));
 27 }
 28
 29 void add(int u,int v)
 30 {
 31     e[tot].to=v;
 32     e[tot].nxt=head[u];
 33     head[u]=tot++;
 34 }
 35 bool Color(int u)
 36 {
 37     for(int i=head[u];i!=-1;i=e[i].nxt)
 38     {
 39         int v=e[i].to;
 40         if(!col[v])
 41         {
 42             col[v]=!col[u];
 43             if(!Color(v))
 44             {
 45                 return false;
 46             }
 47         }
 48         else if(col[v]==col[u])
 49         {
 50             return false;
 51         }
 52     }
 53     return true;
 54 }
 55 bool find(int u)
 56 {
 57     for(int i=head[u];i!=-1;i=e[i].nxt)
 58     {
 59         int v=e[i].to;
 60         if(!vis[v])
 61         {
 62             vis[v]=true;
 63             if(link[v]==-1||find(link[v]))
 64             {
 65                 link[v]=u;
 66                 return true;
 67             }
 68         }
 69     }
 70     return false;
 71 }
 72 int n,m;
 73 int main()
 74 {
 75     while(~scanf("%d%d",&n,&m))
 76     {
 77         init();
 78         while(m--)
 79         {
 80             int u,v;
 81             scanf("%d%d",&u,&v);
 82             add(u,v);
 83             add(v,u);
 84         }
 85         col[1]=1;
 86         if(!Color(1))
 87         {
 88             puts("No");
 89             continue;
 90         }
 91         int ans=0;
 92         for(int i=1;i<=n;i++)
 93         {
 94             memset(vis,false,sizeof(vis));
 95             if(find(i))
 96             {
 97                 ans++;
 98             }
 99         }
100         printf("%d\n",ans/2);
101     }
102     return 0;
103 }

【BFS染色】

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<queue>
  8 using namespace std;
  9 const int maxn=2e2+3;
 10 const int maxm=maxn*maxn;
 11 struct edge
 12 {
 13     int to;
 14     int nxt;
 15 }e[maxm];
 16 int tot;
 17 int head[maxn];
 18 int col[maxn];
 19 bool vis[maxn];
 20 int link[maxn];
 21 void init()
 22 {
 23     tot=0;
 24     memset(head,-1,sizeof(head));
 25     memset(col,0,sizeof(col));
 26     memset(link,-1,sizeof(link));
 27 }
 28
 29 void add(int u,int v)
 30 {
 31     e[tot].to=v;
 32     e[tot].nxt=head[u];
 33     head[u]=tot++;
 34 }
 35 bool Color(int u)
 36 {
 37     queue<int> Q;
 38     Q.push(u);
 39     while(!Q.empty())
 40     {
 41         u=Q.front();
 42         Q.pop();
 43         for(int i=head[u];i!=-1;i=e[i].nxt)
 44         {
 45             int v=e[i].to;
 46             if(!col[v])
 47             {
 48                 col[v]=!col[u];
 49                 Q.push(v);
 50             }
 51             else if(col[v]==col[u])
 52             {
 53                 return false;
 54             }
 55         }
 56     }
 57     return true;
 58 }
 59 bool find(int u)
 60 {
 61     for(int i=head[u];i!=-1;i=e[i].nxt)
 62     {
 63         int v=e[i].to;
 64         if(!vis[v])
 65         {
 66             vis[v]=true;
 67             if(link[v]==-1||find(link[v]))
 68             {
 69                 link[v]=u;
 70                 return true;
 71             }
 72         }
 73     }
 74     return false;
 75 }
 76 int n,m;
 77 int main()
 78 {
 79     while(~scanf("%d%d",&n,&m))
 80     {
 81         init();
 82         while(m--)
 83         {
 84             int u,v;
 85             scanf("%d%d",&u,&v);
 86             add(u,v);
 87             add(v,u);
 88         }
 89         col[1]=1;
 90         if(!Color(1))
 91         {
 92             puts("No");
 93             continue;
 94         }
 95         int ans=0;
 96         for(int i=1;i<=n;i++)
 97         {
 98             memset(vis,false,sizeof(vis));
 99             if(find(i))
100             {
101                 ans++;
102             }
103         }
104         printf("%d\n",ans/2);
105     }
106     return 0;
107 }

匈牙利算法:

http://www.cnblogs.com/itcsl/p/6741020.html

时间: 2024-11-10 00:54:58

【01染色法判断二分匹配+匈牙利算法求最大匹配】HDU The Accomodation of Students的相关文章

匈牙利算法 求最大匹配

不断找增广路,直到没有增广路,每找到一条增广路匹配数就加1 //hungary const int X=100,Y=100; int match[Y];// initial to -1 bool vis[Y]; int g[X][Y]; bool dfs(int x){ for(int y=1;y<=Y;y++){ if(g[x][y]&&!vis[y]){ vis[y]=1; if(match[y]==-1||dfs(match[y])){ match[y]=x; return t

匈牙利算法求最大匹配(HDU-4185 Oil Skimming)

如下图:要求最多可以凑成多少对对象 ? 大佬博客:https://blog.csdn.net/cillyb/article/details/55511666 模板: int link[maxn],vis[maxn]; bool dfs(int x) { for(int i = 1; i <= num; i++) { if(!vis[i] && cp[x][i]) { vis[i] = 1; if(link[i] == 0 || dfs(link[i])) { link[i] = x;

最大二分匹配匈牙利算法的python实现

二分图匹配是很常见的算法问题,一般用匈牙利算法解决二分图最大匹配问题,但是目前网上绝大多数都是C/C++实现版本,没有python版本,于是就用python实现了一下深度优先的匈牙利算法,本文使用的是递归的方式以便于理解,然而迭代的方式会更好,各位可以自行实现. 1.二分图.最大匹配 什么是二分图:二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(

HDU 1068 Girls and Boys(二分匹配--匈牙利算法)

Problem Description the second year of the university somebody started a study on the romantic relations between the students. The relation "romantically involved" is defined between one girl and one boy. For the study reasons it is necessary to

HDU 3729 二分匹配匈牙利算法

I'm Telling the Truth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1482    Accepted Submission(s): 740 Problem Description After this year’s college-entrance exam, the teacher did a survey in

HDU-3729 二分匹配 匈牙利算法

题目大意:学生给出其成绩区间,但可能出现矛盾情况,找出合理组合使没有说谎的人尽可能多,并按maximum lexicographic规则输出组合. //用学生去和成绩匹配,成绩区间就是学生可以匹配的成绩 #include <iostream> #include <queue> #include <vector> #define N 100005 using namespace std; struct Node { int f,t; }; Node lis[65]; in

hdu 2063 (二分匹配 匈牙利算法)

过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22693    Accepted Submission(s): 9797 Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做par

hihocoder 1122最大二分匹配匈牙利算法

#include <cstdio> #include <iostream> #include <algorithm> #include <queue> #include <cmath> #include <cstring> #include <stack> #include <set> #include <map> #include <vector> using namespace st

HDU1507 Uncle Tom&#39;s Inherited Land* 二分图匹配 匈牙利算法 黑白染色

原文链接http://www.cnblogs.com/zhouzhendong/p/8254062.html 题目传送门 - HDU1507 题意概括 有一个n*m的棋盘,有些点是废的. 现在让你用1*2的矩形覆盖所有的不废的点,并且不重叠,问最多可以覆盖多少个1*2的矩形,输出方案,有SPJ. 输入描述: 多组数据,每组首先两个数n,m(如果n和m为0,则结束程序) 然后给出k 然后给出k个二元组(x,y)表示废点的坐标. 题解 按照前两片博文的算法已经不行了,因为方案不对了. 所以我们要进行