hdu 3572 Task Schedule
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 3572 Task Schedule相关的知识,希望对你有一定的参考价值。
Task Schedule
题意:有N个任务,M台机器。每一个任务给S,P,E分别表示该任务的(最早开始)开始时间,持续时间和(最晚)结束时间;问每一个任务是否能在预定的时间区间内完成;
注:每一个任务一个时间只能由一台机器加工,(意味着可以随意离散加工的时间点,只要所用的时间点之和为P即可;将天数变成点建图)每一台机器一个时间点也只能加工一个任务;
重点是构图:如果将任务抽象成一个点,所需的时间P变成从该点流出的流量(从源点流入边的容量~~)那么只需按照输入顺序标记为点号与源点s连边,边的容量为P即可;但是点的流量又是怎么"流"出去的呢?流出去只是"时间"问题;即一个任务点最多消耗一个时间点,输入的是一个时间区间(区间很小),我们就可以离散化时间点,之后对区间内的时间点进行连边;边权自然是1了;全部的时间点流向汇点t;边权为机器的数量m;即指每天满载运行时,看是否"最大流"能与s(源点)那边的边权之和(一个割,Yes就表示是最小割)相等;
ps:注意在建立时间点连边的时候,时间点不是之间的Si->Ei;而是在前面n个任务之后;所以标号+n;
Dinic算法;296MS 12452K
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<map> #include<queue> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> #include<stack> #include<set> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define inf 0x3f3f3f3f typedef __int64 ll; template<typename T> void read1(T &m) { T x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+‘0‘); } const int M = 404*404*2; int head[M<<1],tot; struct Edge{ int to,w,Next; Edge(){} Edge(int to,int w,int nx):to(to),w(w),Next(nx){} }e[M<<1]; inline void ins(int u,int v,int w) { e[tot] = Edge{v,w,head[u]}; head[u] = tot++; } typedef pair<int,int> PII; #define MK make_pair #define A first #define B second priority_queue<PII,vector<PII>,greater<PII> > Q; bool vs[160016]; int dist[M]; ll Djistra(int s,int t) { while(!Q.empty()) Q.pop(); fill(vs,vs+t+1,false); fill(dist,dist+t+1,inf); dist[s] = 0; Q.push(MK(0,s)); while(!Q.empty()){ PII tmp = Q.top();Q.pop(); int u = tmp.B; if(vs[u]) continue; vs[u] = true; if(u == t) return dist[t]; for(int id = head[u];~id;id = e[id].Next){ int v = e[id].to,cost = e[id].w; if(dist[v] > dist[u] + cost){ dist[v] = dist[u] + cost; Q.push(MK(dist[v],v)); } } } } int main() { int n,T,kase = 1; read1(T); while(T--){ read1(n); int s = 0, t = (n-1)*(n-1)+1; int u,v1,v2,x; MS1(head);tot = 0; rep0(i,0,n-1){ // n-1行特殊,只要加竖线即可; rep0(j,1,n){//注意j一定要从1开始; read1(x); u = i*(n-1)+j; v1 = (i-1)*(n-1)+j; v2 = i*(n-1)+j-1; if(i == 0) v1 = s; if(j == 1) v2 = t; ins(u,v1,x);ins(v1,u,x); ins(u,v2,x);ins(v2,u,x); } read1(x); u = i*(n-1)+n-1; ins(u,s,x);ins(s,u,x); } rep0(j,1,n){ read1(x); u = (n-2)*(n-1)+j; ins(u,t,x);ins(t,u,x); } read1(x); out(Djistra(s,t)); puts(""); } return 0; }
以上是关于hdu 3572 Task Schedule的主要内容,如果未能解决你的问题,请参考以下文章
hdu 3572 Task Schedule (Dinic模板)