【海岛帝国系列赛】No.7 海岛帝国:神圣之日

50237242海岛帝国:神圣之日

【试题描述】

     战争持续九个月了。“购物券”WHT的军队还在跟恐怖分子僵持着。WHT和LJX已经向“公务员”告急,情况不宜乐观。YSF为守护帝国决定打开“够累 的”星际仓库来化解恐怖分子的威胁。他和LTJ、WHT、LJX、YSM、LYF等人来到了传说中的星际仓库的防爆门前。“郭同学”TONY,“演 员”KLINT,“美的”STEVE……都被恐怖分子的间谍困在里面。由于情况复杂,恐怖分子在门上加了一层层密码,如果没有顺利答对,“蝴蝶”将会引 爆。整个城市将毁灭。门上有这样一幅图,一排有两个空位,地下散落着N枚“微型机器人”其中编号1,2,3表示TX型号(呵呵呵,大家都知道“州长” 吧)4,5,6表示T-5000型号,每排必须有TX、T-5000型号各一个。当把两个机器人插在一排时,如果这两个机器人互相感应就会亮起红灯。要求 尽量让有感应的机器人插在一起。请问如何摆放,才能让最多的机器人满足条件?

【输入要求】

* 第一行两个正整数N,M,表示有N个机器人,有M个关系道
* 接下来M行:每行两个数A,B表示机器人A和B之间有感应

 

【输出要求】

* 一行:表示能满足的最大值

 

【输入实例】

6 5
1 4
1 5
2 5
2 6
3 4

 

【输出实例】

3

 

【其他说明】

依旧,
M均小于40
N均小于10

 

【试题分析】

 这里用到了二分图匹配,所以我们先来了解一下,什么是二分图。

 简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。

区别二分图,关键是看点集是否能分成两个独立的点集。
上图中U和V构造的点集所形成的循环圈不为奇数,所以是二分图。
上图中U和V和W构造的点集所形成的的循环圈为奇数,所以不是二分图。

最大匹配

编辑
求二分图最大匹配可以用最大流或者匈牙利算法。
 
最大匹配
给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是一个匹配.
选择这样的边数最大的子集称为图的最大匹配问题(maximal matching problem)
如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配.

算法

求最大匹配的一种显而易见的算法是:先找出全部匹配,然后保留匹配数最多的.但是这个算法的复杂度为边数的指数级函数.因此,需要寻求一种更加高效的算法.
增广路的定义(也称增广轨或交错轨):
若P是图G中一条连通两个未匹配顶点的路径,并且属M的边和不属M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径.
由增广路的定义可以推出下述三个结论:
1-P的路径长度必定为奇数,第一条边和最后一条边都不属于M.
2-P经过取反操作可以得到一个更大的匹配M'.
3-M为G的最大匹配当且仅当不存在相对于M的增广路径.
 
设G=(V,E)是一个无向图。如顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属两个不同的子集。则称图G为二分图。也就是说在二分图中,顶点可以分为两个集合X和Y,每一条边的两个顶点都分别位于X和Y集合中。如下图所示:

 

1 最大匹配
    在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是一个匹配。选择这样的边数最大的子集称为图的最大匹配问题,最大匹配的边数称 为最大匹配数.如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。如果在左右两边加上源汇点后,图G等价于一 个网络流,最大匹配问题可以转为最大流的问题。解决此问的匈牙利算法的本质就是寻找最大流的增广路径。上图中的最大匹配如下图红边所示:

 

2 最优匹配

最优匹配又称为带权最大匹配,是指在带有权值边的二分图中,求一个匹配使得匹配边上的权值和最大。一般X和Y集合顶点个数相同,最优匹配也是一个完备匹配,即每个顶点都被匹配。如果个数不相等,可以通过补点加0边实现转化。一般使用KM算法解决该问题。

 

3 最小覆盖

二分图的最小覆盖分为最小顶点覆盖和最小路径覆盖:

①最小顶点覆盖是指最少的顶点数使得二分图G中的每条边都至少与其中一个点相关联,二分图的最小顶点覆盖数=二分图的最大匹配数;

②最小路径覆盖也称为最小边覆盖,是指用尽量少的不相交简单路径覆盖二分图中的所有顶点。二分图的最小路径覆盖数=|V|-二分图的最大匹配数;

 

4 最大独立集

    最大独立集是指寻找一个点集,使得其中任意两点在图中无对应边。对于一般图来说,最大独立集是一个NP完全问题,对于二分图来说最大独立集=|V|-二分图的最大匹配数。如下图中黑色点即为一个最大独立集:

设G=(V,E)是一个无向图。如顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属两个不同的子集。则称图G为二分图。也就是说在二分图中,顶点可以分为两个集

X和Y,每一条边的两个顶点都分别位于X和Y集合中。

【以上内容为转载】

 

求二分图最大匹配的方法最容易想到的就是找出全部匹配,然后输出配对数最多的。但这种方法的时间复杂度非常高,那么,有没有更好的方法呢?

当然,如果找到一条增广路,那么配对数就会加一,它的本质就是一条路径的起点和终点都是未配对的点。如果在当下再也找不到增广路,那么当前就是最大匹配了。

【代码】

 1 #include<iostream>
 2 using namespace std;
 3 int e[101][101];
 4 int match[101];
 5 int book[101];
 6 int n,m;
 7 int dfs(int u)
 8 {
 9     int i;
10     for(i=1;i<=n;i++)
11         if(book[i]==0&&e[u][i]==1)
12         {
13             book[i]=1;
14             if(match[i]==0||dfs(match[i]))
15             {
16                 match[i]=u;
17                 match[u]=i;
18                 return 1; 
19             }
20         }
21     return 0;
22 }
23 int main()
24 {
25     int i,j,t1,t2,sum=0;
26     scanf("%d%d",&n,&m);
27     for(int i=1;i<=m;i++)
28     {
29         cin>>t1>>t2;
30         e[t1][t2]=1;
31         e[t2][t1]=1;
32     }
33     for(i=1;i<=n;i++) match[i]=0;
34     for(i=1;i<=n;i++)
35     {
36         for(j=1;j<=n;j++) book[j]=0;
37         if(dfs(i)) sum++; 
38     }
39     printf("%d",sum);
40 }
View Code

 

 

posted @ 2016-06-22 13:44  wxjor  阅读(269)  评论(0编辑  收藏  举报