1. 程式人生 > >HDU - 3572-Task Schedule

HDU - 3572-Task Schedule

amp 結束時間 view can 分享 sed 不同 node printf

題目大意:給N個任務,M臺機器。每個任務有最早才能開始做的時間S,最晚完成時間 E,

和持續工作的時間P。每個任務可以由不同的機器進行,但是在同一時刻,一臺機器最多只能

執行一個任務. 問存不存在可行的工作時間。

思路:網絡流建邊好藍啊!!!一直在想怎麽用時間 t 建邊,好像進入了一個怪圈粗不來!!!

看來題解的思路就懂了,乍一看不是太難嘛,可是自己寫就寫不來,還是菜啊,哎!!!!!!

我們先設一個s點,然後從s向 每個工作建邊,且邊的權值為P,然後每個工作向它的起始時間

和結束時間的所有點建邊權值為1,然後所有天數向e建邊,權值為m。然後跑最大流,如果

最大流等於所有P的和則能完成,否則不能完成。

ps :還學到了一個優化!!

技術分享
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<vector>
 4 #include<queue>
 5 #include<cstring>
 6 using namespace std;
 7 const int N=1010;
 8 const int M=251000+7;
 9 const int inf=0x3f3f3f3f;
10 int e,s,deth[N],n,m,cnt,head[N];
11 bool vis[N];
12 struct
node 13 { 14 int t,v,nx; 15 }edge[M<<1]; 16 void add(int from,int to,int v) 17 { 18 edge[cnt].t=to; 19 edge[cnt].v=v; 20 edge[cnt].nx=head[from]; 21 head[from]=cnt++; 22 23 edge[cnt].t=from; 24 edge[cnt].v=0; 25 edge[cnt].nx=head[to]; 26 head[to]=cnt++; 27 }
28 bool bfs() 29 { 30 memset(deth,0,sizeof(deth)); 31 queue<int> Q; 32 Q.push(s); deth[s]=1; 33 while(!Q.empty()) 34 { 35 int cur=Q.front(); Q.pop(); 36 if(cur==e) return true; 37 for(int i=head[cur];~i;i=edge[i].nx) 38 { 39 int now=edge[i].t; 40 if(!edge[i].v || deth[now]) continue; 41 deth[now]=deth[cur]+1; 42 Q.push(now); 43 } 44 } 45 return false; 46 } 47 int dfs(int cur,int p) 48 { 49 if(cur==e) return p; 50 int res=0; 51 for(int i=head[cur];~i;i=edge[i].nx) 52 { 53 int now=edge[i].t; 54 if(!edge[i].v || deth[now]!=deth[cur]+1) continue; 55 int f=dfs(now,min(p-res,edge[i].v)); 56 res+=f; 57 edge[i].v-=f; edge[i^1].v+=f; 58 if(res==p) break; 59 } 60 if(!res) deth[cur]=1; //這個優化一定要加!!!!! 61 return res; 62 } 63 int Dinic() 64 { 65 int ans=0; 66 while(bfs()) ans+=dfs(s,inf); 67 return ans; 68 } 69 void init() 70 { 71 cnt=0; 72 memset(head,-1,sizeof(head)); 73 } 74 int main() 75 { 76 int T; scanf("%d",&T); 77 for(int cas=1;cas<=T;cas++) 78 { 79 init(); 80 scanf("%d%d",&n,&m); 81 int tot=0; s=0; e=501+n; 82 for(int i=1;i<=n;i++) 83 { 84 int p,f,t; scanf("%d%d%d",&p,&f,&t); 85 tot+=p; 86 add(s,i+500,p); 87 for(int j=f;j<=t;j++) add(i+500,j,1); 88 } 89 for(int i=1;i<=500;i++) add(i,e,m); 90 int ans=Dinic(); 91 if(tot==ans) printf("Case %d: Yes\n\n",cas); 92 else printf("Case %d: No\n\n",cas); 93 } 94 return 0; 95 }
View Code

HDU - 3572-Task Schedule