【bzoj1003】[ZJOI2006]物流运输 最短路+dp

传送门:嘿原题在这

题意:给出一个图,求1~m的最短路,但其中有些点在某些时间段会不能用,题目保证有解。

我们可以很(不)容易的看出递推关系式dp[i]=min(dp[i],dp[j]+cost[j+1][i]+k)(0<=j

//bzoj1003[ZJOI2006]物流运输
//by dadatu
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define lim 1010
using namespace std;

queue q;
int v[lim],head[lim],nextt[lim],c[lim],visit[lim],dist[lim],tag[lim],dp[lim],f[lim][lim],cost[lim][lim];
int n,m,e,k,d,tot=0;

void add_edge(int x,int y,int z){v[++tot]=y;c[tot]=z;nextt[tot]=head[x];head[x]=tot;}
void spfa()
{
	memset(dist,inf,sizeof(dist));memset(visit,0,sizeof(visit));
	q.push(1);visit[1]=1;dist[1]=0;
	while(!q.empty())
	{
		int x=q.front();q.pop();visit[x]=0;
		for (int i=head[x];i;i=nextt[i])
		{
			int y=v[i];
			if (!tag[y]&&dist[y]>dist[x]+c[i])
			{
				 dist[y]=dist[x]+c[i];
				 if (!visit[y]) q.push(y),visit[y]=1;
			}
		}

	}
}

int main()
{
	scanf("%d%d%d%d",&n,&m,&k,&e);
	for (int i=1;i<=e;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		add_edge(x,y,z);add_edge(y,x,z);
	}
	scanf("%d",&d);
	for (int i=1;i<=d;i++)
	{
		int p,l,r;
		scanf("%d%d%d",&p,&l,&r);
		for (int j=l;j<=r;j++) f[p][j]=1;//记录一下l至r这段时间p码头被封
	}
	for (int i=1;i<=n;i++)
	{
		for (int j=i;j<=n;j++)
		{
			memset(tag,0,sizeof(tag));
			for (int x=1;x<=m;x++)
				for (int y=i;y<=j;y++) tag[x]|=f[x][y];//被封就打标记
			spfa();
			if (dist[m]



你可能感兴趣的:(bzoj,图论-spfa,动态规划-简单dp)