P1772 [ZJOI2006]物流运输 dp+最短路

题意:给出一个图,给出这个图要走多少次(一天一次)

   给出每一个点在哪一次(天)不能用

   给出每一次改变路径的花费

   让我们求走n次(天)的最小花费

思路:dp+最短路

   状态转移方程为:dp[i]=mn(dp[i],dp[j]+k+tmp2[j+1][i]*(i-j));

   于是,我们需要求出每一个tmp2【i】【j】,表示的意思是在从i到j的天数内走这一条路径的花费

   那么要想求出tmp2,我们就需要枚举天数段,求出每一个区间内的值,

   想要求出每一个区间内的值,就需要得出在这个区间内不能够用的点

      

 1 for(int i=1;i<=n;i++)
 2     for(int j=i;j<=n;j++){
 3         memset(visnot,0,sizeof(vis));
 4         for(int y=i;y<=j;y++)
 5         for(int u=1;u<=m;u++){
 6             if(tmp1[u][y]) visnot[u]=1;
 7         }
 8         SPFA();
 9         tmp2[i][j]=dis[m];
10     }
View Code

然后最后再跑一遍dp过程即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int inf=0x3f3f3f3f;
 5 const int maxn=400;
 6 int tmp1[maxn][maxn];
 7 int tmp2[maxn][maxn];
 8 int visnot[30];
 9 int vis[30];int dis[30];
10 ll dp[30];
11 struct node
12 {
13     int v,w,nxt;
14 }G[maxn]; int head[maxn]; int num;
15 void add(int u,int v,int w)
16 {
17     G[++num].v=v;G[num].w=w;G[num].nxt=head[u];head[u]=num;
18 }
19 ll mn(ll t1,ll t2)
20 {
21     if(t1<=t2) return t1;
22     else return t2;
23 }
24 void SPFA()
25 {
26     queue<int>q;
27     memset(vis,0,sizeof(vis));
28     memset(dis,inf,sizeof(dis));
29     q.push(1);
30     vis[1]=1; dis[1]=0;
31     while(!q.empty()){
32         int u=q.front();
33         q.pop();
34         vis[u]=0;
35         for(int i=head[u];i;i=G[i].nxt){
36             int v=G[i].v,w=G[i].w;
37             if(visnot[v]) continue;
38             if(dis[v]>dis[u]+w){
39                 dis[v]=dis[u]+w;
40                 if(!vis[v]){
41                     vis[v]=1;
42                     q.push(v);
43                 }
44             }
45         }
46     }
47 }
48 int main()
49 {
50     int n,m,k,e;
51     scanf("%d%d%d%d",&n,&m,&k,&e);
52     for(int i=1;i<=e;i++){
53         int u,v,w;
54         scanf("%d%d%d",&u,&v,&w);
55         add(u,v,w);
56         add(v,u,w);
57     }
58     int T;
59     scanf("%d",&T);
60     while(T--){
61         int cnt,u,v;
62         scanf("%d%d%d",&cnt,&u,&v);
63         for(int i=u;i<=v;i++){
64             tmp1[cnt][i]=1;
65         }
66     }
67     for(int i=1;i<=n;i++)
68     for(int j=i;j<=n;j++){
69         memset(visnot,0,sizeof(vis));
70         for(int y=i;y<=j;y++)
71         for(int u=1;u<=m;u++){
72             if(tmp1[u][y]) visnot[u]=1;
73         }
74         SPFA();
75         tmp2[i][j]=dis[m];
76     }
77     for(int i=1;i<=n;i++)
78         dp[i]=1e16;
79     for(int i=1;i<=n;i++){
80         dp[i]=1ll*tmp2[1][i]*i;
81         for(int j=1;j<i;j++){
82             dp[i]=mn(dp[i],dp[j]+1ll*k+1ll*tmp2[j+1][i]*(i-j));
83         }
84     }
85     printf("%lld\n",dp[n]);
86     return 0;
87 }
View Code

 

        

posted @ 2020-04-18 10:52  古比  阅读(119)  评论(0编辑  收藏  举报