第一题
为图着色问题,参见:http://blog.youkuaiyun.com/njust_ecjtu/article/details/21338619
扩展题:推荐blog---http://blog.youkuaiyun.com/chdhust/article/details/8333567
也可以用图着色模型求解,当区间不重合就着色。此题也有多项式解法。
先对开始时间排序,利用算法导论提及的活动安排---贪心算法,每次活动尽可能多的选择不重合的时间段组成一个集合。
下一次活动则在剔除前面已经选完的时间段中也尽可能多的选择不重合的时间段组成一个集合。。依次类推
以下为代码:
#include <iostream>
#include <algorithm>
#include "vld.h"//这个如果大家没有注释掉即可,为visual leak detector的头文件
using namespace std;
struct meet_time
{
int start;
int end;
};
int min_meeting(meet_time *m ,int n);
bool is_overlap(meet_time m1,meet_time m2);//指排序后的
int main()
{
//meet_time m[11]={{0,6},{1,4},{2,13},{3,5},{3,8},{5,7},{5,9},{6,10},{8,11},{8,12},{12,14}};
meet_time m[4]={{1,5},{2,3},{3,4},{3,6}};
int len = 4;
for(int i = 0;i < len;i++)
{
cout<<m[i].start<<" "<<m[i].end<<" | ";
}
cout<<endl;
int count = min_meeting(m ,len);
cout<<count<<endl;
}
struct cmp
{
bool operator()(meet_time m1,meet_time m2)
{
return m1.start < m2.start;
}
}my_cmp;
int min_meeting(meet_time *m ,int n)
{
bool *used = new bool[n];
int min_color = 0;
memset(used,false,n*sizeof(bool));
//先排序
sort(m,m+n,my_cmp);
for(int i = 0; i < n ;i++)
{
if (!used[i])
{
min_color++;
}
meet_time temp = m[i];
for (int j = i+1;j < n;j++)
{
if (!is_overlap(temp,m[j]))
{
if(!used[j])
{
//有非重叠的
temp = m[j];//作为下一次的对象!
used[j] = true;
}
}
}
}
delete used;
return min_color;
}
//[) 左闭右开
bool is_overlap(meet_time m1,meet_time m2)//指排序后的
{
if(m1.end <= m2.start)return false;
return true;
}