求出最大流,再判断是否满流
先不理解为什么要这样建图
后来看了这一篇题解
http://blog.csdn.net/u012350533/article/details/12361003
把0看做源点st
把每一个任务看做一个点
st到每个任务连边,容量为p,表示任务完成需要的天数
每个任务到每个任务的开始至结束时间连边,容量为1,表示这个任务可以在这些天完成
每一天向汇点ed连边,容量为m,表示一天最多运行m个任务
然后判断最大流是否等于执行完所有任务所需要的时间
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 8 const int maxn = 50005; 9 const int INF = (1 << 30) - 1; 10 11 struct Edge{ 12 int v,next,c; 13 }e[10*maxn]; 14 15 int st,ed,lev[maxn],first[maxn],now[maxn],ecnt; 16 int n,m; 17 18 void init(){ 19 memset(first,-1,sizeof(first)); 20 ecnt = 0; 21 } 22 23 void addedges(int u,int v,int c){ 24 e[ecnt].next = first[u]; 25 e[ecnt].v = v; 26 e[ecnt].c = c; 27 first[u] = ecnt++; 28 29 e[ecnt].next = first[v]; 30 e[ecnt].v = u; 31 e[ecnt].c = 0; 32 first[v] = ecnt++; 33 } 34 35 bool bfs(){ 36 queue<int> q; 37 while(!q.empty()) q.pop(); 38 q.push(st); 39 memset(lev,-1,sizeof(lev)); 40 lev[st] = 0; 41 while(!q.empty()){ 42 int x = q.front();q.pop(); 43 for(int i = first[x];~i;i = e[i].next){ 44 int v = e[i].v; 45 if(lev[v] < 0 && e[i].c > 0){ 46 lev[v] = lev[x] + 1; 47 q.push(v); 48 } 49 } 50 } 51 return lev[ed] != -1; 52 } 53 54 int dfs(int p,int minf){ 55 if(p == ed || minf == 0) return minf; 56 for(int &i = now[p];~i;i = e[i].next){ 57 int v = e[i].v; 58 if(lev[v] == lev[p] + 1 && e[i].c > 0){ 59 int d = dfs(v,min(e[i].c,minf)); 60 if(d > 0){ 61 e[i].c -= d; 62 e[i^1].c += d; 63 return d; 64 } 65 } 66 } 67 return 0; 68 } 69 70 int dinic(){ 71 int max_flow = 0,p1; 72 while(bfs()){ 73 memcpy(now,first,sizeof(first)); 74 while((p1 = dfs(st,INF)) > 0) 75 max_flow += p1; 76 } 77 return max_flow; 78 } 79 80 int main(){ 81 int T; 82 int kase = 0; 83 scanf("%d",&T); 84 while(T--){ 85 scanf("%d %d",&n,&m); 86 init(); 87 st = 0; 88 int maxx = -1; 89 int sum = 0; 90 for(int i = 1;i <= n;i++){ 91 int p,s,e; 92 scanf("%d %d %d",&p,&s,&e);sum+=p; 93 maxx = max(maxx,e); 94 addedges(st,i,p); 95 for(int j = s;j <= e;j++) addedges(i,j+n,1); 96 } 97 98 ed = n + maxx + 1; 99 for(int j = 1;j <= maxx;j++) addedges(j+n,ed,m); 100 101 int ans = dinic(); 102 printf("Case %d: ",++kase); 103 if(ans == sum) puts("Yes"); 104 else puts("No"); 105 puts(""); 106 } 107 return 0; 108 }
时间: 2024-12-28 20:57:16