POJ - 2584(二分匹配入门)
来源:互联网 发布:python电影推荐系统 编辑:程序博客网 时间:2024/06/05 18:30
T-Shirt Gumbo
Description
Input
A single data set has 4 components:
- Start line - A single line:
START X
where (1 <= X <= 20) is the number of contestants demanding shirts. - Tolerance line - A single line containing X space-separated pairs of letters indicating the size tolerances of each contestant. Valid size letters are S - small, M - medium, L - large, X - extra large, T - extra extra large. Each letter pair will indicate the range of sizes that will satisfy a particular contestant. The pair will begin with the smallest size the contestant will accept and end with the largest. For example:
MX
would indicate a contestant that would accept a medium, large, or extra large T-shirt. If a contestant is very picky, both letters in the pair may be the same. - Inventory line - A single line:
S M L X T
indicating the number of each size shirt in Boudreaux and Thibodeaux's inventory. These values will be between 0 and 20 inclusive. - End line - A single line:
END
After the last data set, there will be a single line:
ENDOFINPUT
Output
T-shirts rock!
Otherwise, output:
I'd rather not wear a shirt anyway...
Sample Input
START 1ST0 0 1 0 0ENDSTART 2SS TT0 0 1 0 0ENDSTART 4SM ML LX XT0 1 1 1 0ENDENDOFINPUT
Sample Output
T-shirts rock!I'd rather not wear a shirt anyway...I'd rather not wear a shirt anyway...
很纯的二分匹配,把每一件衣服弄成一个节点即可,
二分匹配的过程是在寻找增广路,
图1是我给出的二分图中的一个匹配:[1,5]和[2,6]。图2就是在这个匹配的基础上找到的一条增广路径:3->6->2->5->1->4。我们借由它来描述一下二分图中的增广路径的性质:
(1)有奇数条边。
(2)起点在二分图的左半边,终点在右半边。
(3)路径上的点一定是一个在左半边,一个在右半边,交替出现。(其实二分图的性质就决定了这一点,因为二分图同一边的点之间没有边相连,不要忘记哦。)
(4)整条路径上没有重复的点。
(5)起点和终点都是目前还没有配对的点,而其它所有点都是已经配好对的。(如图1、图2所示,[1,5]和[2,6]在图1中是两对已经配好对的点;而起点3和终点4目前还没有与其它点配对。)
(6)路径上的所有第奇数条边都不在原匹配中,所有第偶数条边都出现在原匹配中。(如图1、图2所示,原有的匹配是[1,5]和[2,6],这两条配匹的边在图2给出的增广路径中分边是第2和第4条边。而增广路径的第1、3、5条边都没有出现在图1给出的匹配中。)
(7)最后,也是最重要的一条,把增广路径上的所有第奇数条边加入到原匹配中去,并把增广路径中的所有第偶数条边从原匹配中删除(这个操作称为增广路径的取反),则新的匹配数就比原匹配数增加了1个。(如图2所示,新的匹配就是所有蓝色的边,而所有红色的边则从原匹配中删除。则新的匹配数为3。)
不难想通,在最初始时,还没有任何匹配时,图1中的两条灰色的边本身也是增广路径。因此在这张二分图中寻找最大配匹的过程可能如下:
(1)找到增广路径1->5,把它取反,则匹配数增加到1。
(2)找到增广路径2->6,把它取反,则匹配数增加到2。
(3)找到增广路径3->6->2->5->1->4,把它取反,则匹配数增加到3。
(4)再也找不到增广路径,结束。
当然,这只是一种可能的流程。也可能有别的找增广路径的顺序,或者找到不同的增广路径,最终的匹配方案也可能不一样。但是最大匹配数一定都是相同的。(http://blog.csdn.net/xuguangsoft/article/details/7861988)
下面给出代码:
#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<vector>using namespace std;#define MAXN (400+5)#define Set(a, v) memset(a, v, sizeof(a))#define For(i, a, b) for(int i = (a); i <= (b); i++)#define Fort(i, a, b) for(int i = (a); i < (b); i++)struct node{int s, t;};vector<int> G[MAXN];int num[MAXN], size[150], link[MAXN];node nodes[MAXN];bool vis[MAXN];void init(){For(i, 0, 401) G[i].clear();}bool dfs(int now){Fort(i, 0, G[now].size()){int v = G[now][i]; if(vis[v]) continue;vis[v] = true;if(link[v] == -1 || dfs(link[v])){link[v] = now;return true;}}return false;}int huargy(int n){int ret = 0;Set(link, -1);For(i, 1, n){Set(vis, 0);vis[i] = true;ret += dfs(i);}return ret;}int main(){char tmp[20];size['S'] = 1; size['M'] = 2; size['L'] = 3; size['X'] = 4; size['T'] = 5;while(scanf("%s", tmp) != EOF){if(strlen(tmp) > 5) break;init();int n;scanf("%d", &n);For(i, 1, n){scanf("%s", tmp);nodes[i] = (node){size[tmp[0]], size[tmp[1]]};}num[0] = n;For(i, 1, 5){scanf("%d", &num[i]);num[i] += num[i-1];}scanf("%s", tmp);For(i, 1, n) For(j, num[nodes[i].s-1]+1, num[nodes[i].t]) G[i].push_back(j);if(huargy(n) == n) printf("T-shirts rock!\n");else printf("I'd rather not wear a shirt anyway...\n");}return 0;}
- POJ - 2584(二分匹配入门)
- 二分匹配(入门)
- 二分图匹配(入门) 之 poj 1274
- POJ 1469-COURSES(二分图匹配入门-匈牙利算法)
- poj 1274 (二分匹配)
- poj 2584 T-Shirt Gumbo 二分匹配
- poj (3343)二分匹配+二分
- poj 3041(二分匹配,匈牙利)
- poj 3041 Asteroids (二分匹配)
- poj 3041 Asteroids (二分匹配)
- POJ 3020 Antenna Placement (二分匹配)
- POJ 2446 Chessboard (二分匹配)
- POJ 2446 Chessboard(二分图匹配)
- poj 1469 COURSES(二分匹配模板)
- POJ 1161 Walls(二分图匹配)
- POJ 2446 Chessboard(二分图匹配)
- poj 1469 COURSES (二分图匹配)
- POJ 2289(多重匹配+二分)
- 关于IE兼容,发布后变成了IE9(浏览器IE9兼容模式,文档IE7标准模式)
- CSS Positioning(定位)
- 枚举类
- Oracle视图view
- Ubuntu学习笔记一
- POJ - 2584(二分匹配入门)
- codeforces723AThe New Year: Meeting Friends+水题
- 矩阵快速幂入门 + 求Fibonacci数列
- iOS全局返回按钮定制问题解决方案
- 操作系统(8)--并发性学习笔记
- mysql使用问题
- codeforces#375(div.2)723D - Lakes in Berland dfs+bfs
- 利用mathematica制作二维码
- Linux洗C语言基础编程——折半查找法