poj 2771 有点难度最大独立集
来源:互联网 发布:淘宝运送方式怎么设置 编辑:程序博客网 时间:2024/06/05 14:55
题意:一个老师要带一些学生去旅游 , 下面任意两个学生至少要满足下面一个条件:
1、身高相差要超过40cm
2、性别相同
3、最喜欢的音乐属于不同类型
4、最喜欢的体育比赛相同
解 法:我们首先这样来考虑这个问题 , 以上4个条件 , 至少满足一个条件 , 因此对于满足有很多情况, 那么我们反过来想,如果所有条件都不满足 , 那么这个两个人肯定不能同时去 , 这中思想只需要一种情况 , 因此相对于正面解决简单很多,所以对于这中题目 , 我们往往从反面来做。
再 重新回到这个题目 , 如果两个人不能同时去 , 那么我们在这两个人之间连一条边 , 因此在我们所得到的图中,肯定是不存在环(环中至少存在两个点)的 , 因此一个人要么是男生, 要么是女生 , 由这样看 , 我们就能把这个图 ,变成一个二分图, 对于这个二分图 , 如果两个点之间存在直接的边相连 , 那么这两个人就只能去一个 , 再进一步思考 , 我们就能得到,只要求出这个的最大独立集 , 就是这个题目的答案
代码:
1、身高相差要超过40cm
2、性别相同
3、最喜欢的音乐属于不同类型
4、最喜欢的体育比赛相同
解 法:我们首先这样来考虑这个问题 , 以上4个条件 , 至少满足一个条件 , 因此对于满足有很多情况, 那么我们反过来想,如果所有条件都不满足 , 那么这个两个人肯定不能同时去 , 这中思想只需要一种情况 , 因此相对于正面解决简单很多,所以对于这中题目 , 我们往往从反面来做。
再 重新回到这个题目 , 如果两个人不能同时去 , 那么我们在这两个人之间连一条边 , 因此在我们所得到的图中,肯定是不存在环(环中至少存在两个点)的 , 因此一个人要么是男生, 要么是女生 , 由这样看 , 我们就能把这个图 ,变成一个二分图, 对于这个二分图 , 如果两个点之间存在直接的边相连 , 那么这两个人就只能去一个 , 再进一步思考 , 我们就能得到,只要求出这个的最大独立集 , 就是这个题目的答案
代码:
#include#include#include#include#includeusing namespace std;#define MAXN 510#define INF 1000000#define max(x , y) (x)>(y)?(x):(y)#define min(x , y) (x)<(y)?(x):(y)int n , m; // 记录每条边的权值int pre[MAXN] ; // 记录和y中点匹配的点是哪个点vectorgrap[MAXN];int high[MAXN] ;char male[MAXN];char music[MAXN][111] , play[MAXN][111];int cx[MAXN] , cy[MAXN];void init(){ memset(pre ,0 , sizeof(pre)); for(int i =1; i <= n; i++) { grap[i].clear(); } memset(cx ,-1 , sizeof(cx)); memset(cy ,-1 , sizeof(cy));}bool match(int i) // 寻找增广路{ for(int j =0; j < grap[i].size(); j++) { int v = grap[i][j]; if(!pre[v]) { pre[v] = 1; if(cy[v] == -1 || match(cy[v])) { cx[i] = v; cy[v] = i; return true; } } } returnfalse;}int km(){ int i; int res =0; for(i = 1; i<= n; i++) { if(cx[i] == -1) { memset(pre , 0 , sizeof(pre)); if(match(i)) res += 1; } else res += 1; } returnres;}int main(){ int t; cin>>t; while(t--) { scanf("%d" , &n); init(); int i , j , x , y , k = n; for(i = 1; i <= n; i++) scanf("%d %c %s %s" , &high[i] ,&male[i] , music[i] , play[i]); n = 1, m = 1; for(i = 1; i <= k; i++)//确定二分图 if(male[i] == 'M') pre[i] = n++; else pre[i] = m++; for(i = 1; i <= k; i++) for(j = i+1; j <= k; j++) { if(abs(high[i]-high[j]) > 40) continue; if(male[i] == male[j]) continue; if(strcmp(music[i],music[j]) != 0) continue; if(strcmp(play[i] , play[j]) == 0) continue; x = pre[i] , y = pre[j]; if(male[i] == 'M') { grap[x].push_back(y); if(cx[x] == -1 && cy[y] ==-1) cx[x] = y , cy[y] = x; } else { grap[y].push_back(x); if(cx[y] == -1 && cy[x] ==-1) cx[y] = x , cy[x] = y; } } n -= 1; x = km(); cout<<k-x<<endl; } return0;}
0 0
- poj 2771 有点难度最大独立集
- POJ 2771 最大独立集
- poj 2771 二分图最大独立集
- poj 2771 最大独立点集
- POJ 2771 最大独立集 匈牙利算法
- Poj 1419 最大独立集
- POJ 1466 最大独立集
- POJ 1419 最大独立集
- POJ 3692 最大独立集
- poj 1466 最大独立集
- poj 2724 最大独立集
- POJ 2771 Guardian of Decency (最大独立集Hungary)
- poj 2771 二分图最大独立集 学生出游
- POJ 2771 Guardian of Decency(最大独立点集)
- POJ 2771 Guardian of Decency 最大独立集
- POJ 2771 二分图的最大独立集
- 【POJ】2771 Guardian of Decency 最大独立集
- POJ 2771 Guardian of Decency(二分图最大独立集)
- poj 2762 判断有向图是…
- 求强连通分量几种算法的比较
- poj 3207 简单的2-SAT问题
- zoj 1654 中等二分匹配
- poj 2195 最优匹配算法的优化
- poj 2771 有点难度最大独立集
- uva 11419最小点覆盖和…
- poj 3522 MST性质的运用
- MST中求任意两点条路径上的最长边…
- uva 1265 (LA 4848)
- poj 2793 有难度的点连通分量应用
- poj 2662 最短路算法的扩展应用
- hdu 4725 有点深度的最短路
- hdu 4738 2013杭州网络赛一题