poj 1698
来源:互联网 发布:阿里办公软件 编辑:程序博客网 时间:2024/06/07 23:06
题目概述
alice接了N部电影的拍摄工作,所有电影在同一天开工,每周只有固定几天拍,其余时间不拍,电影必须在w周内拍完,alice至少需要去拍d天,问alice能否完成所有电影拍摄
alice每天只能去拍一部电影,每周第一天是周日
时限
1000ms/3000ms
输入
第一行整数times,其后times组数据,每组数据第一行整数N,其后N行,每行九个整数,前七个只有1或0,1表示每周这一天可拍,0反之,其后是d,w
限制
1<=times<=20;1<=N<=20;1<=d<=50;1<=w<=50
输出
每行一个字符串,若能完成所有拍摄,为Yes,否则为No
样例输入
2
2
0 1 0 1 0 1 0 9 3
0 1 1 1 0 0 0 6 4
2
0 1 0 1 0 1 0 9 4
0 1 1 1 0 0 0 6 2
样例输出
Yes
No
讨论
图论,应该算是二分图,但还没看到那部分,只能先用网络流处理,利用Isap+gap优化,主要还是构图,将每一天看做一个节点,编号0到349,因为最多50周,电影也看做节点,编号350到369,然后虚构一个源点370,汇点371,从源点出发流向每部电影,流量就是需要拍摄的天数,从每部电影到拍摄周内拍摄的那些天,流量是1,因为每天只能拍一部,同理这些天都连接到汇点,流量也是1,如此,若能全拍,则最大流量应为所有电影需要拍摄天数和
实现层次上,isap的gap优化不能垄断所有return,因为程序可能不从gap优化结束,而是从原始while判断条件结束,虽然有点不可思议,但确实如此,所有层次都有剩余,但源点已经被排除了,不再有最短路,程序结束,着实不知道如何发生的,好在并不难修改,给fun函数添加正常return出口,而gap优化改为break出while循环,这样就能照顾到所有情况了,这样说有点抽象,代码里会体现
题解状态
728K,16MS,C++,1777B
题解代码
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;#define INF 0x3f3f3f3f#define MAXN 374#define memset0(a) memset(a,0,sizeof(a))int N, S = 370, T = 371;//电影总数 以及虚构的源点汇点 这两点编号是固定的int R[MAXN][MAXN], dis[MAXN], from[MAXN], gap[MAXN];//isap四大数组 残量矩阵 层次 父节点编号 每个层次的节点数bool mk[7];//marked 用于将每周拍摄时间进行构图queue<int>q;//bfs辅助队bool fun(){ int sum = 0;//所有电影合计拍摄天数 for (int p = 0; p < N; p++) { for (int i = 0; i < 7; i++) scanf("%d", &mk[i]);//input int d, w;//拍摄需求天数 拍摄周数 scanf("%d%d", &d, &w);//input sum += d; R[S][p + 350] = d;//将源点与电影连接 残量是需求天数 for (int i = 0; i < 7; i++) {//完成电影到每天再到汇点的构图 if (!mk[i])//这天不拍 直接跳过 continue; for (int u = 0; u < w; u++) R[p + 350][i + 7 * u] = R[i + 7 * u][T] = 1;//将电影与拍摄周内拍摄日相连 拍摄日再连到汇点 残量都是1 } } N = 372;//既然汇点是371 那么N就是372了 虽然有点浪费 但好在数据规模小 for (int p = 0; p < N; p++)//初始化层次数组 不能直接用0 这点在poj 1273里被卡了好几次 因为0在N范围内 后面可能会被视为可行边 dis[p] = N;//初始化为N就足矣 因为在范围内的两点 最远不过N-1的层次差 dis[T] = 0;//汇点到自己是0层次 下面是bfs 这些都是一样的 gap[0]++; q.push(T); while (!q.empty()) { int a = q.front(); q.pop(); for (int p = 0; p < N; p++) if (dis[p] == N&&R[p][a]) { q.push(p); dis[p] = dis[a] + 1; gap[dis[p]]++; } } int most = 0, cur = S, flow = INF;//下面是isap算法主体 while (dis[S] < N) { int p; for (p = 0; p < N && (!R[cur][p] || dis[cur] != dis[p] + 1); p++); if (p != N) { from[p] = cur; flow = min(flow, R[cur][p]); cur = p; if (cur == T) { most += flow; while (cur != S) { p = from[cur]; R[p][cur] -= flow; R[cur][p] += flow; cur = p; } flow = 1; } } else { if (!--gap[dis[cur]]) break; dis[cur] = N; for (int p = 0; p < N; p++) if (R[cur][p] && dis[cur] > dis[p] + 1) dis[cur] = dis[p] + 1; gap[dis[cur]]++; if (cur != S) cur = from[cur]; } } return most == sum;//算法现在有了正常的出口 没有这行结果必然会错}int main(void){ //freopen("vs_cin.txt", "r", stdin); //freopen("vs_cout.txt", "w", stdout); int times; scanf("%d", ×);//input while (times--) { scanf("%d", &N);//input if (fun()) printf("Yes\n")//output; else printf("No\n");//output memset0(R); memset0(gap);//dis有初始化 from会被覆盖 这两个需要初始化 }}
EOF
- poj 1698
- poj 1698(最大流)
- poj 1698 最大流
- poj 1698 最大流
- poj 1698
- POJ 1698 最大流
- POJ 1698 网络流
- 网络流 poj 1698
- poj 1698日程安排
- poj 1698 线段树
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- PHP 闭包函数及Closure对象的总结
- dtrace 在redhat 6.2上 安装
- webview的两个方法:setWebChromeClient和setWebClient
- js实现CkeckBox全选与反选
- 密码盘 纪中 3067 状压dp
- poj 1698
- Android源码编译---Nexus 设备驱动
- 如何修改Android系统的默认亮度
- 什么是Web App、Hybrid App、 Native App以及区别,当前主流移动和应用程序类型
- 获取session用户信息
- Dubbo项目搭建
- pgAdmin远程连接阿里云主机的PostgreSQL-9.5
- java异常处理
- HDU 1176 免费馅饼 最详细的解答(对于dp新手来说非常好的题目)