hdu 2883 kebab
2015-04-07 21:55
169 查看
题意:和hdu 3572相似,不同的是这里是n个人来,要从si时间开始,ei时间前结束,共有ni个肉串,每个肉串烤cost个单位时间。
所以处理时候与hdu3572略不同的是讲一整个时间区间先离散,作为一个点,如果某人的起始和结束时间包含某个时间区间,说明那个人在这个区间里面能烤任意时间(当然前提是不超过这个区间长度,比如某段时间区间长度为10,那个人可以烤0~10的任意时间),所以将那个人的任务与该时间点连边,容量控制为inf。其他的处理和3572那题是一样的
dinic过不了去学isap,姿势没学对一直T。。最后换成sap真是不容易
所以处理时候与hdu3572略不同的是讲一整个时间区间先离散,作为一个点,如果某人的起始和结束时间包含某个时间区间,说明那个人在这个区间里面能烤任意时间(当然前提是不超过这个区间长度,比如某段时间区间长度为10,那个人可以烤0~10的任意时间),所以将那个人的任务与该时间点连边,容量控制为inf。其他的处理和3572那题是一样的
#include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 #define ls rt << 1 #define rs rt << 1 | 1 #define pi acos(-1.0) #define eps 1e-8 typedef long long ll; const int inf = 0x3f3f3f3f; const int N = 1000; struct node{ int v, w, nxt; int cap; }e[N*N]; int head ; int pre ; int dep ; int gap ; int cur ; int tot ; int n, m, nn; int cnt, ccnt, x; int s , t ; int st, ed; void init() { st = cnt = 0; memset( head, -1, sizeof( head ) ); } void add( int u, int v, int w, int rw = 0 ) { e[cnt].v = v; e[cnt].w = 0; e[cnt].cap = w; e[cnt].nxt = head[u]; head[u] = cnt++; e[cnt].v = u; e[cnt].w = 0; e[cnt].cap = rw; e[cnt].nxt = head[v]; head[v] = cnt++; } int sap() { memset( dep, 0, sizeof( dep ) ); memset( gap, 0, sizeof( gap ) ); memcpy( cur, head, sizeof( head ) ); int u = st; pre[u] = -1; int flow = 0; nn = ed + 1; gap[0] = nn; while( dep[st] < nn ) { if( u == ed ) { int minn = inf; for( int i = pre[u]; ~i; i = pre[e[i^1].v] ) minn = min( minn, e[i].cap - e[i].w ); for( int i = pre[u]; ~i; i = pre[e[i^1].v] ) { e[i].w += minn; e[i^1].w -= minn; } u = st; flow += minn; } bool f = 0; for( int i = cur[u]; ~i; i = e[i].nxt ) { int v = e[i].v; if( dep[v] + 1 == dep[u] && e[i].cap - e[i].w > 0 ) { f = 1; cur[u] = pre[v] = i; u = v; break; } } if( f ) continue; int minn = nn; for( int i = head[u]; ~i; i = e[i].nxt ) { if( minn > dep[e[i].v] && e[i].cap - e[i].w > 0 ) { cur[u] = i; minn = dep[e[i].v]; } } gap[dep[u]]--; if( !gap[dep[u]] ) break; dep[u] = minn + 1; gap[dep[u]]++; if( u != st ) u = e[pre[u]^1].v; } return flow; } int main() { while( ~scanf("%d%d", &n, &m) ) { init(); int ni, cost; ccnt = 0; x = 1; int sum = 0; for( int i = 1; i <= n; ++i ) { scanf("%d%d%d%d", &s[i], &ni, &t[i], &cost); add( st, i, cost * ni ); sum += cost * ni; tot[++ccnt] = s[i]; tot[++ccnt] = t[i]; } tot[0] = 0; sort( tot+1, tot + ccnt + 1 ); for( int i = 2; i <= ccnt; ++i ) { if( tot[x] != tot[i] ) tot[++x] = tot[i]; } ed = x + n + 1; for( int i = 1; i <= x; ++i ) // seg { int tmp = tot[i] - tot[i-1]; add( i+n, ed, tmp * m ); for( int j = 1; j <= n; ++j ) //task { if( s[j] <= tot[i-1] && tot[i] <= t[j] ) add( j, i+n, inf ); } } int ans = sap(); if( ans == sum ) puts("Yes"); else puts("No"); } return 0; }
dinic过不了去学isap,姿势没学对一直T。。最后换成sap真是不容易
相关文章推荐
- HDU 2883 kebab 网络流
- hdu 2883 kebab
- kebab (hdu 2883 网络流判满流 关键是缩点)
- hdu 2883 kebab(最大流dinic邻接表)
- HDU 2883 kebab(离散化+最大流)
- HDU 2883 kebab 最大流判满流
- HDU 2883 —— kebab
- 【网络流】 hdu 2883 kebab
- hdu 3572 Task Schedule hdu 2883 kebab 最大流
- HDU 2883kebab(网络流之最大流)
- hdu 3572 Task Schedule hdu 2883 kebab 最大流
- hdu 2883 kebab 【网络最大流】
- HDU 2883 kebab 最大流(纯靠建图)
- hdu 2883 kebab
- HDU 2883 kebab (最大流)
- HDU 2883 kebab 最大流建模
- HDU 2883 kebab(最大流,满流)
- 【网络流】 HDU 2883 kebab 离散
- HDU 2883 kebab【最大流】(判断是否满流)
- 【网络流】 HDU 2883 kebab 离散