luogu 1772 物流运输 ZJOI2006 spfa+dp

主要路径上存在时间限制(消失)

因为数据较小(点数较小),利用限制条件在规定时间内分别spfa,(也可用floyd)

再通过dp取最优值

#include<bits/stdc++.h>
#define ll long long 
#define rep(i,x,y) for(register int i=x;i<=y;i++)
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;}
const int N=30;
const int M=1000;
const int T=110;
const int inf=0x3f3f3f3f;

int day,n,rec,m,d,t,dis[N];
int close[N][T],now[N],vis[N];
ll cost[T][T],f[T];

int head[N],tot;
struct node{int v,w,next;}e[M];
void insert(int u,int v,int w){
    e[++tot]=(node){v,w,head[u]};head[u]=tot;
    e[++tot]=(node){u,w,head[v]};head[v]=tot;}

int spfa(int x,int y){
    memset(dis,inf,sizeof dis);
    memset(vis,0,sizeof vis);
    memset(now,0,sizeof now);
    
    rep(i,1,n)rep(j,x,y)
    if(close[i][j]) now[i]=1;
    
    queue<int> q;
    q.push(1);dis[1]=0;vis[1]=1;
    while(!q.empty()){
        int u=q.front();q.pop();vis[u]=0;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].v,w=e[i].w;
            if(now[v]) continue;
            if(dis[u]+w<dis[v]){
                dis[v]=dis[u]+w;
                if(!vis[v]) vis[v]=1,q.push(v);
            }
        }
    }return dis[n];
}
int main(){
    day=read(),n=read(),rec=read(),m=read();
    rep(i,1,m){
        int u=read(),v=read(),w=read();insert(u,v,w);}
    t=read();
    rep(i,1,t){
        int p=read(),u=read(),v=read();
        rep(j,u,v) close[p][j]=1;}
    rep(i,1,day)rep(j,1,day)
        cost[i][j]=spfa(i,j);
    rep(i,1,day){ 
        f[i]=(ll)cost[1][i]*i;
        rep(j,1,i)
        f[i]=min(f[i],f[j]+(ll)cost[j+1][i]*(i-j)+rec);}
    printf("%lld\n",f[day]); return 0;
}

 

posted @ 2018-09-07 11:30  ASDIC减除  阅读(100)  评论(0编辑  收藏  举报