题目大意:给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 }