zoukankan      html  css  js  c++  java
  • P1772 [ZJOI2006]物流运输

    题目地址


     转移方程:

    • dis[i][j]:时间i~j不改变线路的最短路.
    • cost[i]:从第1天到第i天的最低代价.
    • cost[i]=cost[j]+dis(j+1,i)*(i-j)+k(0<=j<i). 

    初始值:

    • cost[0]=-k.

    基本思路:

    • 预处理dis[i][j],进行cost[]转移即可.

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int MAXN=40,MAXM=8e2,MAXTIME=2e2;
    struct Edge{
    	int from,to,w,nxt;
    }e[MAXM];
    int head[MAXN],edgeCnt=1;
    void addEdge(int u,int v,int w){
    	e[++edgeCnt].from=u;
    	e[edgeCnt].to=v;
    	e[edgeCnt].w=w;
    	e[edgeCnt].nxt=head[u];
    	head[u]=edgeCnt;
    }
    struct Node{
    	int v,dis;
    	bool operator <(Node another)const{
    		return dis>another.dis;
    	}
    };
    int m;
    int dis_dijktra[MAXN];
    bool canGo[MAXN]; 
    void dijkstra(){
    	memset(dis_dijktra,0x3f,sizeof(dis_dijktra));
    	priority_queue<Node> q;
    	if(canGo[1])q.push(Node{1,0});
    	dis_dijktra[1]=0;
    	while(!q.empty()){
    		Node nowNode=q.top();
    		q.pop();
    		int nowU=nowNode.v;
    		if(dis_dijktra[nowU]!=nowNode.dis)continue;
    		for(int i=head[nowU];i;i=e[i].nxt){
    			int nowV=e[i].to;
    			if(!canGo[nowV])continue;
    			if(dis_dijktra[nowV]>dis_dijktra[nowU]+e[i].w){
    				dis_dijktra[nowV]=dis_dijktra[nowU]+e[i].w;
    				q.push(Node{nowV,dis_dijktra[nowV]});
    			}
    		}
    	}
    }
    bool timeCanGo[MAXTIME][MAXN];
    int getDis(int l,int r){//时间l到r的距离 
    	memset(canGo,1,sizeof(canGo));
    	for(int i=1;i<=m;i++){
    		for(int j=l;j<=r;j++){
    			if(!timeCanGo[j][i])canGo[i]=0;
    		}
    	}
    	dijkstra();
    	return dis_dijktra[m];
    }
    ll dis[MAXTIME][MAXTIME];
    int n,k;
    ll cost[MAXTIME];
    int main(){
    	int e;
    	scanf("%d%d%d%d",&n,&m,&k,&e);
    	for(int i=1;i<=e;i++){
    		int a,b,w;
    		scanf("%d%d%d",&a,&b,&w);
    		addEdge(a,b,w);
    		addEdge(b,a,w);
    	}
    	int d;
    	scanf("%d",&d);
    	memset(timeCanGo,1,sizeof(timeCanGo));
    	for(int i=1;i<=d;i++){
    		int p,a,b;
    		scanf("%d%d%d",&p,&a,&b);
    		for(int j=a;j<=b;j++){
    			timeCanGo[j][p]=0;
    		}
    	}
    	for(int l=1;l<=n;l++){
    		for(int r=1;r<=n;r++){
    			dis[l][r]=getDis(l,r);
    		}
    	}
    	memset(cost,0x3f,sizeof(cost));
    	cost[0]=-k;
    	for(int i=1;i<=n;i++){
    		for(int j=0;j<i;j++){
    			cost[i]=min(cost[i],cost[j]+dis[j+1][i]*(i-j)+k);
    		}
    	}
    	printf("%d
    ",cost[n]);
    	return 0;
    }
    
  • 相关阅读:
    什么是面向对象以及实现类的封装
    验证码的实现
    cookie和session简单的用法
    类似百度的分页的函数
    实现登陆功能

    微信公众号开发
    常量的注意
    php数组转换成xml格式数据
    xml格式数据转数组的函数
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11838664.html
Copyright © 2011-2022 走看看