HDU - 3572 Task Schedule(网络流)(入门好题)
题意:
有 $m$ 台机器,一台机器同一时刻只能够做一个任务,任务可以被中断并给另一个空闲的机器去完成;
现在有 $n$ 个任务,每个任务有 $Pi , si , ei $, 分别表示该任务完成所需要的 任务量,开始时间,截止时间;
问 是否能够在规定时间内完成所有任务。
思路:
设定 $S = 0$ 为超级源点,将 $S$ 与每一个任务点相连,流量为$P[i]$,每个任务点与其 $si$ 到 $ei$ 范围内相连,流量为1,最后将所有任务的时间区间与 $T$ 相连,流量为 $m$;
跑一遍最大流之后判断是否大于 $\sum_{i=1}^{n} Pi $,若大于等于,则能够完成所给的任务,反之则不能。 感觉是一道比较好的网络流入门题目
1 /* 2 * @Author: WindyStreet 3 * @Date: 2018-07-31 16:00:05 4 * @Last Modified by: WindyStreet 5 * @Last Modified time: 2018-07-31 19:14:55 6 */ 7 #include<bits/stdc++.h> 8 9 using namespace std; 10 11 #define X first 12 #define Y second 13 #define eps 1e-2 14 #define gcd __gcd 15 #define pb push_back 16 #define PI acos(-1.0) 17 #define lowbit(x) (x)&(-x) 18 #define bug printf("!!!!!\n"); 19 #define mem(x,y) memset(x,y,sizeof(x)) 20 21 typedef long long LL; 22 typedef long double LD; 23 typedef pair<int,int> pii; 24 typedef unsigned long long uLL; 25 26 const int maxn = 1e3+2; 27 const int INF = 1<<30; 28 const int mod = 1e9+7; 29 30 struct Edge{ 31 int from,to,cap,flow; 32 }; 33 struct node 34 { 35 int p,s,e; 36 }s[maxn]; 37 38 struct Dinic 39 { 40 int n,m,s,t; 41 vector<Edge>edge; 42 vector<int>G[maxn]; 43 bool vis[maxn]; 44 int d[maxn]; 45 int cur[maxn]; 46 void init(int n){ 47 this->n = n; 48 for(int i=0;i<=n;i++)G[i].clear(),edge.clear(); 49 } 50 void addedge(int from,int to,int cap){ 51 edge.pb((Edge){from,to,cap,0}); 52 edge.pb((Edge){to,from,0,0}); 53 m = edge.size(); 54 G[from].pb(m-2); 55 G[to].pb(m-1); 56 } 57 bool bfs(){ 58 mem(vis,0); 59 queue<int>Q; 60 Q.push(s); 61 d[s] = 0; 62 vis[s] = 1; 63 while(!Q.empty()){ 64 int x = Q.front(); Q.pop(); 65 int sz = G[x].size(); 66 for(int i=0;i<sz;++i){ 67 Edge &e = edge[G[x][i]]; 68 if(!vis[e.to] && e.cap>e.flow){ 69 vis[e.to] = 1 ; 70 d[e.to] = d[x] + 1; 71 Q.push(e.to); 72 } 73 } 74 } 75 return vis[t]; 76 } 77 int dfs(int x,int a){ 78 if(x == t || a == 0)return a; 79 int flow = 0,f; 80 int sz = G[x].size(); 81 for(int &i = cur[x];i<sz;i++){ 82 Edge &e = edge[G[x][i]]; 83 if(d[x] + 1 == d[e.to] && (f = dfs(e.to,min(a,e.cap - e.flow)))>0){ 84 e.flow += f; 85 edge[G[x][i]^1].flow -=f; 86 flow += f; 87 a -= f; 88 if(a==0)break; 89 } 90 } 91 if(!flow) d[x] = -2; 92 return flow; 93 } 94 int maxflow(int s,int t){ 95 this->s = s; this -> t = t; 96 int flow = 0; 97 while(bfs()){ 98 mem(cur,0); 99 flow += dfs(s,INF); 100 } 101 return flow; 102 } 103 }; 104 105 void solve(){ 106 int n,m,len = -1,st = 0,ed = 1001,sum = 0; 107 Dinic dinic; 108 scanf("%d%d",&n,&m); 109 for(int i=1;i<=n;i++){ 110 scanf("%d%d%d",&s[i].p,&s[i].s,&s[i].e); 111 len = max(len,s[i].e); // 记录最大的时间 112 sum += s[i].p; 113 dinic.addedge(st,i,s[i].p); // 将 S 与每个任务点相连 114 for(int j = s[i].s ;j <= s[i].e;j++ ){ 115 dinic.addedge(i,j+n,1); // 将每个任务点与其相对应的时间区间相连 116 } 117 } 118 for(int i = 1;i<=len;i++) 119 { 120 dinic.addedge(i+n,ed,m); // 将所有的时间区间与 T汇点相连 121 } 122 int ans = dinic.maxflow(st,ed); 123 if(sum<=ans){ // 判断最大流是否大于等于所需时间 124 printf("Yes\n\n"); 125 }else{ 126 printf("No\n\n"); 127 } 128 return; 129 } 130 131 int main() 132 { 133 // freopen("in.txt","r",stdin); 134 // freopen("out.txt","w",stdout); 135 // ios::sync_with_stdio(false); 136 int t = 1,cas = 1; 137 scanf("%d",&t); 138 while(t--){ 139 printf("Case %d: ",cas++); 140 solve(); 141 } 142 return 0; 143 }