[VJ 费用流] 小R的烦恼

题目

戳这

思路

直接讲吧。

  1. 限制每天的 a i ai ai : 我们将学生分为两类,濒死的学生归在 S S S一边,活着的学生归在 T T T一边。对于每一天,我们将第 i i i天拆成 i x ix ix i y iy iy i x ix ix为濒死的, i y iy iy为活着的。把 S S S i x ix ix连流量为 a i ai ai,费用为0的边,把 i y iy iy T T T连流量为 a i ai ai,费用为0的边。
  2. 对于学校的提供 : 对于一个学校 j j j, 可将它看做一个节点,例如标号为 2 ∗ n + j 2 * n + j 2n+j, 然后 S S S向这个点连流量为 l j lj lj,费用为0的边,这个点再向 i y iy iy连一条流量为INF,费用为 p j pj pj的边。就完成了虚拟濒死的人通过学校复活,即学校提供学生的过程。
  3. 对于濒死的人,在第 i i i天不一定要将他复活,可以留到下一天再复活,所以将濒死一边的 i i i号点和 i + 1 i+1 i+1号点连一条流量为 I N F INF INF, 费用为0的边,将死的人留到下一天复活。
  4. 至于第 j j j家医院复活濒死的人,如果这是第 i i i天,并且 i x + d j + 1 < = n ix + dj + 1 <= n ix+dj+1<=n,那么可以将他在 i y + d j + 1 iy + dj + 1 iy+dj+1天复活。就从 i x ix ix i y + d j + 1 iy + dj + 1 iy+dj+1的点连一条流量为 I N F INF INF, 费用为 q j qj qj的点。可能有人会问,难道必须要在 d j + 1 dj + 1 dj+1后复活吗?不是的,因为濒死的人会传到下一天,所以他直接复活是不会影响的。

Code

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXL 105
#define MAXN 10005
#define MAXM 300005
#define LL long long
#define Int register int
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef pair<LL, LL> Pair;
inline void read(LL &x)
{
	x = 0;
	LL f = 1;
	char s = getchar();
	while (s < '0' || s > '9')
	{
		if (s == '-')
			f = -1;
		s = getchar();
	}
	while (s >= '0' && s <= '9')
	{
		x = (x << 3) + (x << 1) + (s ^ 48);
		s = getchar();
	}
	x *= f;
}
LL Min(LL x,LL y)
{
	return x < y ? x : y;
}
struct node
{
    LL to, next, flow, cost;
    node(){}
    node(LL TO,LL NEXT,LL FLOW,LL COST)
    {
    	to = TO;
    	next = NEXT;
    	flow = FLOW;
    	cost = COST;
	}
}Edge[MAXN << 1];
LL tot = -1, head[MAXN], n, m, k;
void AddEdge_Double(LL x,LL y,LL w,LL mon)
{
	Edge[++ tot] = node(y, head[x], w, mon);
    head[x] = tot;
    Edge[++ tot] = node(x, head[y], 0, -mon);
    head[y] = tot;
}
struct cmp
{
	bool operator()(Pair x,Pair y)
	{
		if (x.first < y.first)
			return 0;
		if (x.first == y.first && x.second < y.second)
			return 0;
		return 1;
	}
};
LL h[MAXN], dis[MAXN], Pred[MAXN], Preb[MAXN];
Pair Min_Max_Flow(LL s,LL t)
{
    LL Flow = 0, Cost = 0;
    while ( 1 )
    {
    	memset(h, 0, sizeof h);
    	memset(dis, 0x3f, sizeof dis);
        for (Int i = 0; i < MAXN; ++ i)
        dis[s] = 0;
        priority_queue<Pair, vector<Pair>, cmp> Q;
        Q.push(Pair(0, s));
        while (! Q.empty())
        {
            Pair u = Q.top();
            Q.pop();
            if (u.first != dis[u.second])
				continue;
            if (u.second == t)
				break;
            for (LL i = head[u.second]; ~ i; i = Edge[i].next)
            {
            	node v = Edge[i];
                LL NowCost = Edge[i].cost + h[u.second] - h[v.to];
                if (v.flow > 0 && dis[v.to] > dis[u.second] + NowCost)
                {
                    dis[v.to] = dis[u.second] + NowCost;
                    Q.push(Pair(dis[v.to], v.to));
                    Pred[v.to] = u.second;
                    Preb[v.to] = i;
                }
            }
        }
        if (dis[t] == INF)
            break;
        for (Int i = 0; i < MAXN; ++ i)
            h[i] = Min(h[i] + dis[i], INF);
        LL NowFlow = INF;
        for (LL x = t; x != s; x = Pred[x])
            NowFlow = Min(NowFlow, Edge[Preb[x]].flow);
        Flow += NowFlow;
        Cost += NowFlow * h[t];
        for (LL x = t; x != s; x = Pred[x])
        {
        	Edge[Preb[x]].flow -= NowFlow;
			Edge[Preb[x] ^ 1].flow += NowFlow;
		}
    }
    return Pair(Flow, Cost);
}
LL Abs(LL x)
{
	if (x > 0)
		return x;
	return -x;
}
LL JL(LL x1,LL y1,LL x2,LL y2)
{
	return Abs(x1 - x2) + Abs(y1 - y2);
}
LL Xu(LL x,LL y)
{
	return (x - 1) * m + y;
}
LL a[MAXN], l[MAXN], p[MAXN], d[MAXN], q[MAXN];
int main()
{
	LL T;
	read( T );
	LL cnt = 0;
	while (T --)
	{
		LL Sum = 0;
		tot = -1;
    	memset(head, -1, sizeof head);
    	read( n ); read( m ); read( k );
    	for (Int i = 1; i <= n; ++ i)
    		read( a[i] ), Sum += a[i];
    	for (Int i = 1; i <= m; ++ i)
    		read( l[i] ), read( p[i] );
    	for (Int i = 1; i <= k; ++ i)
    		read( d[i] ), read( q[i] );
    	LL s = 0, t = MAXN - 1;
    	for (Int i = 1; i <= n; ++ i)
    		AddEdge_Double(s, i, a[i], 0),
    		AddEdge_Double(i + n, t, a[i], 0);
		for (Int j = 1; j <= m; ++ j)
		{
			AddEdge_Double(s, 2 * n + j, l[j], 0);
			for (Int i = 1; i <= n; ++ i)
    			AddEdge_Double(2 * n + j, i + n, INF, p[j]);
		}
    	for (Int i = 1; i < n; ++ i)
    		AddEdge_Double(i, i + 1, INF, 0);
		for (Int j = 1; j <= k; ++ j)
		{
			for (Int i = 1; i < n; ++ i)
				if (i + d[j] + 1 <= n)
    				AddEdge_Double(i, i + n + d[j] + 1, INF, q[j]);
		}
    	Pair Ans = Min_Max_Flow(s, t);
    	if (Sum != Ans.first)
    		printf("Case %lld: impossible\n", ++ cnt);
    	else printf("Case %lld: %lld\n", ++ cnt, Ans.second);
	}
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
08-10
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值