您的位置:首页 > 其它

hdu 2883 kebab

2015-04-07 21:55 169 查看
题意:和hdu 3572相似,不同的是这里是n个人来,要从si时间开始,ei时间前结束,共有ni个肉串,每个肉串烤cost个单位时间。

所以处理时候与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真是不容易
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: