资源分配,每个时间点有m个机器可用,要将这资源分配给n个任务中的一些,要求每个任务在自己的时间范围中被分配了p[i]个资源,建图:
建立源,与每个时间点连边,容量为m,每个任务向其对应的时间段中的每个时间点连边,容量1,每个任务向汇连边,容量为该任务需要的时间。
收获:
本题中的有:任务,时间,机器三个对象,但第三个对象是无区别的,所以它的限制就用容量表示,而其它对象都是不同的,所以要用点。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <vector> 5 #define maxn 1010 6 #define oo 0x3f3f3f3f 7 using namespace std; 8 9 struct Edge { 10 int u, v, f; 11 Edge( int u, int v, int f ):u(u),v(v),f(f){} 12 }; 13 struct Dinic { 14 int n, src, dst; 15 vector<Edge> edge; 16 vector<int> g[maxn]; 17 int dep[maxn], cur[maxn]; 18 19 void init( int n, int src, int dst ) { 20 this->n = n; 21 this->src = src; 22 this->dst = dst; 23 for( int u=1; u<=n; u++ ) 24 g[u].clear(); 25 edge.clear(); 26 } 27 void add_edge( int u, int v, int f ) { 28 g[u].push_back( edge.size() ); 29 edge.push_back( Edge(u,v,f) ); 30 g[v].push_back( edge.size() ); 31 edge.push_back( Edge(v,u,0) ); 32 } 33 bool bfs() { 34 queue<int> qu; 35 memset( dep, 0, sizeof(dep) ); 36 qu.push(src); 37 dep[src] = 1; 38 while( !qu.empty() ) { 39 int u=qu.front(); 40 qu.pop(); 41 for( int t=0; t<g[u].size(); t++ ) { 42 Edge &e=edge[g[u][t]]; 43 if( e.f && !dep[e.v] ) { 44 dep[e.v] = dep[e.u]+1; 45 qu.push( e.v ); 46 } 47 } 48 } 49 return dep[dst]; 50 } 51 int dfs( int u, int a ) { 52 if( u==dst || a==0 ) return a; 53 int past=0, remain=a, na; 54 for( int &t=cur[u]; t<g[u].size(); t++ ) { 55 Edge &e = edge[g[u][t]]; 56 Edge &ve = edge[g[u][t]^1]; 57 if( dep[e.v]==dep[u]+1 && e.f && (na=dfs(e.v,min(remain,e.f))) ) { 58 remain -= na; 59 past += na; 60 e.f -= na; 61 ve.f += na; 62 if( remain==0 ) break; 63 } 64 } 65 return past; 66 } 67 int maxflow() { 68 int mf = 0; 69 while( bfs() ) { 70 memset( cur, 0, sizeof(cur) ); 71 mf += dfs(src,oo); 72 } 73 return mf; 74 } 75 }; 76 77 int n, m; 78 int p[maxn], s[maxn], t[maxn], maxd, sum; 79 Dinic D; 80 81 int main() { 82 int T; 83 scanf( "%d", &T ); 84 for( int cas=1; cas<=T; cas++ ) { 85 scanf( "%d%d", &n, &m ); 86 maxd = sum = 0; 87 for( int i=1; i<=n; i++ ) { 88 scanf( "%d%d%d", p+i, s+i, t+i ); 89 maxd = max( t[i], maxd ); 90 sum += p[i]; 91 } 92 D.init( n+maxd+2, n+maxd+1, n+maxd+2 ); 93 for( int i=1; i<=n; i++ ) { 94 D.add_edge( D.src, i, p[i] ); 95 for( int d=s[i]+n; d<=t[i]+n; d++ ) 96 D.add_edge( i, d, 1 ); 97 } 98 for( int d=n+1; d<=n+maxd; d++ ) 99 D.add_edge( d, D.dst, m ); 100 bool ok = D.maxflow()==sum; 101 printf( "Case %d: %s\n\n", cas, ok ? "Yes" : "No" ); 102 } 103 }
时间: 2024-11-05 13:28:52