HDU3572Task Schedule(最大流 ISAP比較快)建图方法不错
Task Schedule
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5007 Accepted Submission(s): 1636
has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted
and processed on different machines on different days.
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
You are given two integer N(N<=500) and M(M<=200) on the first line of each test case. Then on each of next N lines are three integers Pi, Si and Ei (1<=Pi, Si, Ei<=500), which have the meaning described in the description. It is guaranteed that in a feasible
schedule every task that can be finished will be done before or at its end day.
Print a blank line after each test case.
2
4 3
1 3 5
1 1 4
2 3 7
3 5 9 2 2
2 1 3
1 2 2
Case 1: Yes Case 2: Yes
题意:有M个机器,有N个任务。
每一个任务必须在Si 或者以后開始做,在Ei 或者之前完毕。完毕任务必须处理Pi 个时间单位。当中,每一个任务能够在随意(空暇)机器上工作,每一个机器的同一时刻仅仅能工作一个任务。每一个任务在同一时刻仅仅能被一个机器工作,并且任务做到一半能够打断,拿去其它机器做。问:是否能在规定时间内把任务做完。
思路:建图是关键,我们能够选择0为源点,然后源点与每一个任务都连一条边。容量为要求的天数p,然后每一个任务都与对应的时间点连边。边容量为1。最后我们要确定汇点。汇点能够取vt=maxtime+n+1(当中maxtime为结束时间的最大值,n为任务数),这样确定好汇点之后,再在每一个时间点与汇点之间连边。边容量为m,为机器数(表示每一个时间点最多能够有m台机器处理任务),最后推断sum(for all pi)==?SAP就可以。
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define captype int const int MAXN = 1010; //点的总数
const int MAXM = 520010; //边的总数
const int INF = 1<<30;
struct EDG{
int to,next;
captype cap,flow;
} edg[MAXM];
int eid,head[MAXN];
int gap[MAXN]; //每种距离(或可觉得是高度)点的个数
int dis[MAXN]; //每一个点到终点eNode 的最短距离
int cur[MAXN]; //cur[u] 表示从u点出发可流经 cur[u] 号边 void init(){
eid=0;
memset(head,-1,sizeof(head));
}
//有向边 三个參数,无向边4个參数
void addEdg(int u,int v,captype c,captype rc=0){
edg[eid].to=v; edg[eid].next=head[u];
edg[eid].cap=c; edg[eid].flow=0; head[u]=eid++; edg[eid].to=u; edg[eid].next=head[v];
edg[eid].cap=rc; edg[eid].flow=0; head[v]=eid++;
}
//预处理eNode点到全部点的最短距离
void BFS(int sNode, int eNode){
queue<int>q;
memset(gap,0,sizeof(gap));
memset(dis,-1,sizeof(dis));
gap[0]=1;
dis[eNode]=0;
q.push(eNode);
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=head[u]; i!=-1; i=edg[i].next){
int v=edg[i].to;
if(dis[v]==-1){
dis[v]=dis[u]+1;
gap[dis[v]]++;
q.push(v);
}
}
}
}
int S[MAXN]; //路径栈。存的是边的id号
captype maxFlow_sap(int sNode,int eNode, int n){
BFS(sNode, eNode); //预处理eNode到全部点的最短距离
if(dis[sNode]==-1) return 0; //源点到不可到达汇点
memcpy(cur,head,sizeof(head)); int top=0; //栈顶
captype ans=0; //最大流
int u=sNode;
while(dis[sNode]<n){ //推断从sNode点有没有流向下一个相邻的点
if(u==eNode){ //找到一条可增流的路
captype Min=INF ;
int inser;
for(int i=0; i<top; i++) //从这条可增流的路找到最多可增的流量Min
if(Min>edg[S[i]].cap-edg[S[i]].flow){
Min=edg[S[i]].cap-edg[S[i]].flow;
inser=i;
}
for(int i=0; i<top; i++){
edg[S[i]].flow+=Min;
edg[S[i]^1].flow-=Min; //可回流的边的流量
}
ans+=Min;
top=inser; //从这条可增流的路中的流量瓶颈 边的上一条边那里是能够再增流的。所以仅仅从断流量瓶颈 边裁断
u=edg[S[top]^1].to; //流量瓶颈 边的起始点
continue;
}
bool flag = false; //推断是否能从u点出发可往相邻点流
int v;
for(int i=cur[u]; i!=-1; i=edg[i].next){
v=edg[i].to;
if(edg[i].cap-edg[i].flow>0 && dis[u]==dis[v]+1){
flag=true;
cur[u]=i;
break;
}
}
if(flag){
S[top++] = cur[u]; //增加一条边
u=v;
continue;
}
//假设上面没有找到一个可流的相邻点。则改变出发点u的距离(也可觉得是高度)为相邻可流点的最小距离+1
int Mind= n;
for(int i=head[u]; i!=-1; i=edg[i].next)
if(edg[i].cap-edg[i].flow>0 && Mind>dis[edg[i].to]){
Mind=dis[edg[i].to];
cur[u]=i;
}
gap[dis[u]]--;
if(gap[dis[u]]==0) return ans; //当dis[u]这样的距离的点没有了,也就不可能从源点出发找到一条增广流路径
//由于汇点到当前点的距离仅仅有一种,那么从源点到汇点必定经过当前点,然而当前点又没能找到可流向的点,那么必定断流
dis[u]=Mind+1; //假设找到一个可流的相邻点。则距离为相邻点距离+1,假设找不到,则为n+1
gap[dis[u]]++;
if(u!=sNode) u=edg[S[--top]^1].to; //退一条边 }
return ans;
}
int main(){
int T,cas=0,n,m;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
init();
int maxtime=0,sump=0;
for(int i = 1; i<=n; i++){
int P,S,E;
scanf("%d%d%d",&P,&S,&E); sump += P; //总流量
if(E>maxtime)
maxtime = E; addEdg(0,i,P); //源点0到任务i的最大流量为P
for(int j=S; j<=E; j++)
addEdg(i,n+j,1); //任务i到时间点j+n。边最大容量为1
}
int t=maxtime + n +1;
for(int j=1; j<=maxtime; j++)
addEdg(j+n,t,m);<span style="white-space:pre"> </span>//每一个时间点到汇点t,边最大容量为m printf("Case %d: %s\n\n",++cas,maxFlow_sap(0,t,t)==sump? "Yes":"No");
}
}
HDU3572Task Schedule(最大流 ISAP比較快)建图方法不错的更多相关文章
- Codeforces.1045A.Last chance(最大流ISAP 线段树优化建图)
题目链接 \(Description\) 你需要用给定的\(n\)个武器摧毁\(m\)架飞船中的某一些.每架飞船需要被摧毁恰好一次. 武器共三种:1.可以在给定的集合中摧毁一架飞船:2.可以摧毁区间\ ...
- POJ 2391 Ombrophobic Bovines ( 经典最大流 && Floyd && 二分 && 拆点建图)
题意 : 给出一些牛棚,每个牛棚都原本都有一些牛但是每个牛棚可以容纳的牛都是有限的,现在给出一些路与路的花费和牛棚拥有的牛和可以容纳牛的数量,要求最短能在多少时间内使得每头牛都有安身的牛棚.( 这里注 ...
- hdu3572Task Schedule 最大流,判断满流 优化的SAP算法
PS:多校联赛的题目质量还是挺高的.建图不会啊,看了题解才会的. 参考博客:http://blog.csdn.net/luyuncheng/article/details/7944417 看了上面博客 ...
- BZOJ-1070 修车 最小费用最大流+拆点+略坑建图
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3624 Solved: 1452 [Submit][Status] ...
- HDU 3572 Task Schedule (最大流)
C - Task Schedule Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- hdu 3572 Task Schedule(最大流&&建图经典&&dinic)
Task Schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图
#6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- 洛谷 P5331 - [SNOI2019]通信(CDQ 分治优化建图+费用流)
题面传送门 首先熟悉网络流的同学应该能一眼看出此题的建模方法: 将每个点拆成两个点 \(in_i,out_i\),连一条 \(S\to in_i\),容量为 \(1\) 费用为 \(0\) 的边 连一 ...
- [模板] 网络流相关/最大流ISAP/费用流zkw
最大流/ISAP 话说ISAP是真快...(大多数情况)吊打dinic,而且还好写... 大概思路就是: 在dinic的基础上, 动态修改层数, 如果终点层数 \(>\) 点数, break. ...
随机推荐
- 快速排序-php代码实现
<?php function quickSort(array &$a) { $n = count($a); quickSortInternally($a, 0, $n-1); } fun ...
- getattr、setattr、hasattr
写一个演示类 class test(): title="验证getattr.setattr.hasattr方法" def run(self): return "run方法 ...
- [python测试框架] http接口测试框架
https://testerhome.com/topics/5631 Http 接口测试框架 (思路 + 实现中 + 开源 + 可能难产) Http 接口测试框架疑问解答 Fiddler 保存会话 ( ...
- SPOJ 3267 D-query(离散化+在线主席树 | 离线树状数组)
DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...
- ACM程序设计选修课——1018: Common Subsequence(DP)
问题 L: Common Subsequence 时间限制: 1 Sec 内存限制: 32 MB 提交: 70 解决: 40 [提交][状态][讨论版] 题目描述 A subsequence of ...
- 洛谷P4175 - [CTSC2008]网络管理
Portal Description 给出一棵\(n(n\leq8\times10^4)\)个点的带点权的树,进行\(m(m\leq8\times10^4)\)次操作,操作有两种: 修改一个点的点权. ...
- 刷题总结——字符串(ssoj)
题目: 给定n个小的字符串T和一个大的字符串S,先输出T总共再S中出现了多少次 然后q个询问···每次修改S上的一个字母,然后再次输出上述答案··· n小于1000,q<200000,T的总长度 ...
- 学习orm框架及一些看法
首先说说我对现在主流的ORM框架的一些看法: 优点: 让程序员不再关注数据库细节,专心在业务逻辑上,程序员可以不懂数据库就可以开发系统. 让数据库迁移变的非常方便,如果系统需要更改使用的数据库,直接改 ...
- jenkins使用xvfb插件构建虚拟化显示屏自动化测试
1.linux服务器安装xvfb,并启动 参考我的博客:http://www.cnblogs.com/lincj/p/5468505.html 或者网上搜索一下进行安装 2.jenkins安装xvfb ...
- zoj 1425 最大交叉匹配
Crossed Matchings Time Limit: 2 Seconds Memory Limit: 65536 KB There are two rows of positive i ...