1. 程式人生 > >【動態規劃】【最短路】[BZOJ 1003]物流運輸trans

【動態規劃】【最短路】[BZOJ 1003]物流運輸trans

簡直是醉了,這道題本來想了一會兒,然後看了看資料邊的數量頂天了才400然後時間最多才100那麼直接用SPFA 複雜度O(nm2)就可以過了,然後注意一下特別判定是否超過INF可能有資料很極限,判斷一下是否超過了INF沒有才運算,我被這個小問題卡了好久。。。然後就是列舉當前連續一段的起始時間和結束時間然後f(i)=min(f(j)+SPFA(i,j)×(ij)+k)

#include <cstdio>
#include <algorithm>
#include <queue>
#include <iostream>
#include <cstring>
#include <vector> using namespace std; const int MAXE = 20000; const int MAXN = 200; const int MAXM = 40; const int INF = 300000000; struct node{ int v, w; node *next; }Edges[MAXE*2], *ecnt=Edges, *adj[MAXM+10]; bool life[MAXN+10]; int f[MAXN+2], n, m, e, k, now, to, d; pair<int, pair<int,int> > ord[310
]; void addedge(int u, int v, int w){ ++ecnt; ecnt->v = v; ecnt->w = w; ecnt->next = adj[u]; adj[u] = ecnt; } queue<int> que; int dis[MAXM+10]; inline int SPFA(int st, int ed){ for(int i=1;i<=m;i++) dis[i] = INF; memset(life, 0, sizeof life); for
(int i=0;i<d;i++){ if(ord[i].second.first > ed || ord[i].second.second < st) continue; life[ord[i].first] = true; } while(!que.empty()) que.pop(); que.push(1);dis[1] = 0; while(!que.empty()){ now = que.front(); que.pop(); for(node *p=adj[now];p;p=p->next){ to = p->v; if(!life[to] && dis[to] > dis[now] + p->w){ dis[to] = dis[now] + p->w; que.push(to); } } } return dis[m]; } int main(){ int tmp; scanf("%d%d%d%d", &n, &m, &k, &e); for(int i=0;i<e;i++){ scanf("%d%d%d", &now, &to, &tmp); addedge(now, to, tmp); addedge(to, now, tmp); } scanf("%d", &d); for(int i=0;i<d;i++){ scanf("%d%d%d", &tmp, &now, &to); ord[i] = (make_pair(tmp, make_pair(now, to))); } for(int i=1;i<=n;i++){f[i] = INF;} f[0] = -k; for(int i=1;i<=n;i++) for(int j=0;j<i;j++){ if(f[j] >= INF || (tmp = SPFA(j+1, i)) >= INF) continue; f[i] = min(f[i], f[j]+tmp*(i-j)+k); } printf("%d\n", f[n]); return 0; }