P1772 [ZJOI2006]物流运输
Posted $mathcal{Lance1ot}$
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1772 [ZJOI2006]物流运输相关的知识,希望对你有一定的参考价值。
SPFA+DP
常数奇大的线段树维护那些天不能走
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
vector<int>line[250];
vector<int>cost[250];
struct segment_tree
{
bool val[700];
bool tag[700];
void push_down(int root)
{
val[root<<1]|=tag[root];
val[root<<1|1]|=tag[root];
tag[root<<1]|=tag[root];
tag[root<<1|1]|=tag[root];
tag[root]=false;
return ;
}
void updata(int root,int nl,int nr,int l,int r,int value)
{
if(nl>r||nr<l)
return ;
if(nl>=l&&nr<=r)
{
val[root]|=value;
tag[root]|=value;
return ;
}
int mid=(nl+nr)>>1;
push_down(root);
updata(root<<1,nl,mid,l,r,value);
updata(root<<1|1,mid+1,nr,l,r,value);
val[root]=val[root<<1]|val[root<<1|1];
return ;
}
bool check(int root,int nl,int nr,int l,int r)
{
if(nl>r||nr<l)
return false;
if(nl>=l&&nr<=r)
return val[root];
push_down(root);
int mid=(nl+nr)>>1;
return check(root<<1,nl,mid,l,r)|check(root<<1|1,mid+1,nr,l,r);
}
};
segment_tree point[51];
long long dis[201][201];
long long n,m,k,e;
queue<int>q;
bool inque[201];
long long SPFA(int begin,int end,int s,int t)
{
inque[begin]=true;
q.push(begin);
long long dist[201];
for(int i=1;i<=40;i++)
dist[i]=1e+9;
dist[begin]=0;
while(!q.empty())
{
int pas=q.front();
q.pop();
inque[pas]=false;
for(int i=0;i<line[pas].size();i++)
{
int nxt=line[pas][i],spend=cost[pas][i];
if(!point[nxt].check(1,1,n,s,t)&&dist[nxt]>dist[pas]+spend)
{
dist[nxt]=dist[pas]+spend;
if(!inque[nxt])
{
q.push(nxt);
inque[nxt]=true;
}
}
}
}
return dist[end];
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&e);
long long a,b,c;
for(int i=1;i<=e;i++)
{
scanf("%d%d%d",&a,&b,&c);
line[a].push_back(b);
line[b].push_back(a);
cost[a].push_back(c);
cost[b].push_back(c);
}
int d;
scanf("%d",&d);
for(int i=1;i<=d;i++)
{
scanf("%d%d%d",&a,&b,&c);
point[a].updata(1,1,n,b,c,true);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
{
int ha=SPFA(1,m,j,i);
if(ha==1e+9)
{
dis[j][i]=0x7ffffffff;
continue;
}
dis[j][i]=ha*(i-j+1);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=i-1;j++)
dis[1][i]=min(dis[1][j]+dis[j+1][i]+k,dis[1][i]);
printf("%d",dis[1][n]);
}
以上是关于P1772 [ZJOI2006]物流运输的主要内容,如果未能解决你的问题,请参考以下文章