zoukankan      html  css  js  c++  java
  • [zjoi2006][bzoj1003]物流运输(最短路+dp)

    传送门

    学OI时候的习惯,考前发题解可以RP++。

    退役已经8个月了,现在准备自招和高考。接下来的期末考试对我个人来说很重要了,比较作为分班的依据。
    这道题还是简单的,大概一眼就能看出来复杂度至少是n3。

    思路就不细细说了,我们直接暴力地跑n^2次dijkstra,预处理出cost_i_j表示从第i天到第j天不更换路线的最小消耗。如果不存在一条在这段时间里可以走的路,cost_i_j就是0x3f3f3f3f。dijkstra就是每次处理出这段时间里不能走的点,然后常规操作。

    处理出cost_i_j之后就是常规DP了,方程很好想懒得写了,如果没想出来可以阅读代码。

    于是5min时间又码了一篇题解,RP++。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    namespace zjy{
    	inline void read(int &x){
    	x=0;int f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	x*=f;
    	}
    struct EDGE{
    	int nex,w,to;
    }edge[410];
    int head[21],tot,dis[21];
    inline void insert(int from,int to,int w){
    	edge[++tot].nex=head[from];
    	head[from]=tot;
    	edge[tot].to=to;
    	edge[tot].w=w;
    }
    struct POINT{
    	int num;
    	friend bool operator < (POINT a,POINT b){
    		return dis[a.num]<dis[b.num];
    	}
    }point[21];
    int N,M,K,E,D;
    bool close[21][105],vis[21];
    int cost[105][105];
    std::priority_queue<std::pair<int,int> > que;
    void dijkstra(int l,int r){
    	memset(dis,0x3f,sizeof(dis));
    	memset(vis,0,sizeof(vis));
    	for(int x=1;x<=M;x++)
    		for(int i=l;i<=r;i++)
    			if(close[x][i]){
    				vis[x]=1;
    				continue;
    			}	
    	que.push(std::make_pair(0,1));dis[1]=0;
    	while(!que.empty()){
    		int u=que.top().second;
    		que.pop();
    		if(vis[u])
    			continue ;
    		vis[u]=1;
    		for(int i=head[u];i;i=edge[i].nex){
    			if(dis[edge[i].to]>dis[u]+edge[i].w){
    				dis[edge[i].to]=dis[u]+edge[i].w;
    				que.push(std::make_pair(-dis[edge[i].to],edge[i].to));
    			}
    		}
    	}
    	cost[l][r]=dis[M];
    }
    int dp[105];
    int work(){
    	read(N);read(M);read(K);read(E);
    	int x,y,z;
    	for(int i=1;i<=E;i++){
    		read(x);read(y);read(z);
    		insert(x,y,z);
    		insert(y,x,z);
    	}
    	read(D);
    	for(int i=1;i<=D;i++){
    		read(x);read(y);read(z);
    		for(int i=y;i<=z;i++)
    			close[x][i]=1;
    	}
    	for(int i=1;i<=N;i++)
    		for(int j=i;j<=N;j++)
    			dijkstra(i,j);
    	memset(dp,0x3f,sizeof(dp));
    	dp[0]=-K;
        for(int i=1;i<=N;i++)
            for(int j=0;j<=i;j++)
            	if(cost[j+1][i]!=0x3f3f3f3f&&dp[j]!=0x3f3f3f3f)
                    dp[i]=std::min(dp[i],dp[j]+(i-j)*cost[j+1][i]+K);
        std::cout<<dp[N];
    }
    }
    int main(){
    	zjy::work();
    }
    
    /*
    5 5 10 8
    1 2 1
    1 3 3
    1 4 2
    2 3 2
    2 4 4
    3 4 1
    3 5 2
    4 5 2
    4
    2 2 3
    3 1 1             
    3 3 3
    4 4 5
    */
    
  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/sherrlock/p/11136642.html
Copyright © 2011-2022 走看看