shjwudp

导航

 

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1003

解:一个很神奇的dp,预处理所有连续时间段内的最小花费(w[i][j]表示第i天到第j天的最小花费),然后以f[x]表示到第x天为止的最小花费,用f[j]=min(f[j], f[i]+w[i+1][j]+K)更新即可

  1 /*
  2  * Problem:  
  3  * Author:  SHJWUDP
  4  * Created Time:  2015/6/9 星期二 11:06:58
  5  * File Name: 233.cpp
  6  * State: 
  7  * Memo: 
  8  */
  9 #include <iostream>
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13 #include <queue>
 14 
 15 using namespace std;
 16 
 17 const int INF=0x7f7f7f7f;
 18 
 19 const int MaxA=100+7;
 20 const int MaxB=20+7;
 21 
 22 struct Edge {
 23     int v, nt;
 24     int w;
 25     Edge(){}
 26     Edge(int v, int nt, int w):v(v), nt(nt), w(w){}
 27 } edges[MaxB*MaxB*2];
 28 
 29 int head[MaxB], edgeNum;
 30 
 31 struct Data {
 32     int P, a, b;
 33 } op[MaxA];
 34 
 35 int n, m, K, e, d;
 36 int w[MaxA][MaxA];
 37 int f[MaxA];
 38 bool used[MaxA];
 39 void init() {
 40     memset(head, -1, sizeof(head));
 41     edgeNum=0;
 42 }
 43 void addEdge(int u, int v, int w) {
 44     edges[edgeNum]=Edge(v, head[u], w);
 45     head[u]=edgeNum++;
 46 }
 47 void build(int s, int t) {
 48     memset(used, 0, sizeof(used));
 49     for(int i=0; i<d; i++) {
 50         if(op[i].b<s || op[i].a>t) continue;
 51         used[op[i].P]=1;
 52     }
 53 }
 54 namespace Dijkstra {
 55     struct HeapNode {
 56         int d, u;
 57         HeapNode(int d, int u):d(d), u(u) {}
 58         bool operator<(const HeapNode& rhs) const {
 59             return d>rhs.d;
 60         }
 61     };
 62 
 63     int d[MaxB];
 64     int done[MaxB];
 65 
 66     void go(int s) {
 67         priority_queue<HeapNode> Q;
 68         memset(d, 0x7f, sizeof(d));
 69         memset(done, 0, sizeof(done));
 70         
 71         Q.push(HeapNode(0, s)); d[s]=0;
 72         while(!Q.empty()) {
 73             HeapNode x=Q.top(); Q.pop(); 
 74             if(done[x.u]) continue;
 75             done[x.u]=1;
 76             for(int i=head[x.u]; ~i; i=edges[i].nt) {
 77                 Edge& e=edges[i];
 78                 if(used[e.v]) continue;
 79                 if(d[x.u]+e.w<d[e.v]) {
 80                     d[e.v]=d[x.u]+e.w;
 81                     Q.push(HeapNode(d[e.v], e.v));
 82                 }
 83             }
 84         }
 85     }
 86 }
 87 int main() {
 88 #ifndef ONLINE_JUDGE
 89     freopen("in", "r", stdin);
 90 //    freopen("out", "w", stdout);
 91 #endif
 92     while(~scanf("%d%d%d%d", &n, &m, &K, &e)) {
 93         init();
 94         for(int i=0; i<e; i++) {
 95             int a, b, c;
 96             scanf("%d%d%d", &a, &b, &c);
 97             addEdge(a, b, c);
 98             addEdge(b, a, c);
 99         }
100         scanf("%d", &d);
101         for(int i=0; i<d; i++) {
102             scanf("%d%d%d", &op[i].P, &op[i].a, &op[i].b);
103         }
104         for(int i=1; i<=n; i++) {
105             for(int j=i; j<=n; j++) {
106                 build(i, j);
107                 Dijkstra::go(1);
108                 w[i][j]=Dijkstra::d[m];
109                 if(w[i][j]<INF) w[i][j]*=j-i+1;
110             }
111         }
112         for(int j=1; j<=n; j++) {
113             f[j]=w[1][j];
114             for(int i=1; i<j; i++) {
115                 if(w[i+1][j]>=INF || f[i]>=INF) continue;
116                 f[j]=min(f[j], f[i]+w[i+1][j]+K);
117             }
118         }
119         printf("%d\n", f[n]);
120     }
121     return 0;
122 }
View Code

 

posted on 2015-06-09 12:40  shjwudp  阅读(201)  评论(0编辑  收藏  举报