现在的位置: 首页 > 综合 > 正文

BZOJ 1003 ZJOI 2006 物流运输 动态规划+SPFA

2018年01月19日 ⁄ 综合 ⁄ 共 1588字 ⁄ 字号 评论关闭

题目大意:有一些码头由若干条边组成,有些时候有一些码头需要维修,这个期间不能使用这个码头。跟换航线的话会有一定的花费,求规定天数内的最小花费。

思路:最短路方面用SPFA就行,关键是动态规划。这个动规我想了很久,结果到最后发现自己想复杂了。我一开始想的是用SPFA处理出每一个不同的段,然后动规。这样做不仅分段不好分,动规也不好写。之后才发现,一共天数才100,枚举起点和终点才10000,套一个SPFA的O(kn)也不到1qw。。。

CODE:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 110
using namespace std;

int days,points,change,edges,asks;
int cost[MAX][MAX],used[MAX][MAX];
bool v[MAX];
int head[MAX],total;
int next[MAX << 3],aim[MAX << 3],length[MAX << 3];

int f[MAX];
bool vis[MAX];

int dp[MAX];

inline void Add(int x,int y,int len);
inline void SPFA();

int main()
{
	cin >> days >> points >> change >> edges;
	for(int x,y,z,i = 1;i <= edges; ++i) {
		scanf("%d%d%d",&x,&y,&z);
		Add(x,y,z),Add(y,x,z);
	}
	cin >> asks;
	for(int x,y,z,i = 1;i <= asks; ++i) {
		scanf("%d%d%d",&z,&x,&y);
		for(int j = x;j <= y; ++j)
			used[j][z] = true;
	}
	for(int i = 1;i <= days; ++i)
		for(int j = i;j <= days; ++j) {
			memset(v,false,sizeof(v));
			for(int k = i;k <= j; ++k)
				for(int z = 2;z < points; ++z)
					if(used[k][z])	v[z] = true;
			SPFA();
			cost[i][j] = f[points] * (f[points] >= 0x3f3f3f3f ? 1:(j - i + 1));
		}
	memset(dp,0x3f,sizeof(dp));
	dp[0] = 0;
	for(int i = 1;i <= days; ++i)
		for(int j = 0;j < i; ++j)
			dp[i] = min(dp[i],dp[j] + cost[j + 1][i] + change);
	cout << dp[days] - change << endl;
	return 0;
}

inline void Add(int x,int y,int len)
{
	next[++total] = head[x];
	aim[total] = y;
	length[total] = len;
	head[x] = total;
}

inline void SPFA()
{
	static queue<int> q;
	while(!q.empty())	q.pop();
	memset(f,0x3f,sizeof(f));
	memset(vis,false,sizeof(vis));
	q.push(1);
	f[1] = 0;
	while(!q.empty()) {
		int x = q.front(); q.pop();
		vis[x] = false;
		for(int i = head[x];i;i = next[i]) {
			if(v[aim[i]])	continue;
			if(f[aim[i]] > f[x] + length[i]) {
				f[aim[i]] = f[x] + length[i];
				if(!vis[aim[i]])
					vis[aim[i]] = true,q.push(aim[i]);
			}
		}
	}
}

抱歉!评论已关闭.