1. 程式人生 > 實用技巧 >HDU3572 Task Schedule (網路流)

HDU3572 Task Schedule (網路流)

某工廠有 M 臺機器要完成 N 個任務。 第i個任務的開始時間不早於Si, 需要幹Pi天, a並要在不晚於Ei時完成. 一臺機器一天只能幹一個任務,一個認為在同一天只能用一臺機器. 任務完成不需要連續,只要有足夠的天數即可。
能不能搞完這些工作

簡單的最大流

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
const int inf=1e9;
int n,m;
struct node {
    int u,v,w,nxt;
}edge[maxn<<1];
int head[maxn],tot;
void addedge (int u,int v,int w) { edge[tot].u=u; edge[tot].v=v; edge[tot].w=w; edge[tot].nxt=head[u]; head[u]=tot++; edge[tot].u=v; edge[tot].v=u; edge[tot].w=0; edge[tot].nxt=head[v]; head[v]=tot++; } int dep[maxn],inq[maxn],cur[maxn],wjm,maxflow,s,t; bool
bfs () { for (int i=0;i<=t;i++) { cur[i]=head[i]; dep[i]=inf; inq[i]=0; } dep[s]=0; queue<int> q; q.push(s); while (q.size()) { int u=q.front(); q.pop(); inq[u]=0; for (int i=head[u];i!=-1;i=edge[i].nxt) {
int v=edge[i].v; if (dep[v]>dep[u]+1&&edge[i].w) { dep[v]=dep[u]+1; if (inq[v]==0) { q.push(v); inq[v]=1; } } } } if (dep[t]!=inf) return 1; return 0; } int dfs (int u,int flow) { int increase=0; if (u==t) { wjm=1; maxflow+=flow; return flow; } int used=0; for (int i=cur[u];i!=-1;i=edge[i].nxt) { cur[u]=i; int v=edge[i].v; if (edge[i].w&&dep[v]==dep[u]+1) { if (increase=dfs(v,min(flow-used,edge[i].w))) { used+=increase; edge[i].w-=increase; edge[i^1].w+=increase; if (used==flow) break; } } } return used; } int Dinic () { while (bfs()) { wjm=1; while (wjm==1) { wjm=0; dfs(s,inf); } } return maxflow; } int P[maxn],S[maxn],E[maxn]; int main () { int _; scanf("%d",&_); for (int ca=1;ca<=_;ca++) { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d%d%d",P+i,S+i,E+i); //源點為0 //m臺機器為1~m //一共500天,天為m+1~m+500 //一共n個任務,任務為m+500+1~m+500+n //源點向每個機器連一條容量為無限大的邊 //每個機器向每天連一條容量為1的邊 //每天向可以做的任務連一條容量為1的邊 //每個任務向匯點連一條容量為Pi的邊 //最後判斷一下最大流是不是等於每個任務的Pi之和即可 s=0; t=m+n+501; for (int i=0;i<=t;i++) head[i]=-1;tot=0;maxflow=0;wjm=0; for (int i=1;i<=m;i++) addedge(s,i,inf); for (int i=m+1;i<=m+500;i++) for (int j=1;j<=m;j++) addedge(j,i,1); for (int i=1;i<=n;i++) for (int j=S[i];j<=E[i];j++) addedge(j,i+m+500,1); int sum=0; for (int i=1;i<=n;i++) addedge(i+m+500,t,P[i]),sum+=P[i]; if (Dinic()==sum) printf("Case %d: Yes\n\n",ca); else printf("Case %d: No\n\n",ca); } }