吐槽一下,是十分暴力的写法。D[i][j]表示一条在 i - j 时段保持畅通的运输路线的最短距离,然后就是Biubiubiu的DP。关键是D[i][j]直接暴力求出每条边可不可用就可以直接SPFA了,来局昆特牌吗,亲。
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 using namespace std; 5 struct node { 6 int t, v; 7 }; 8 vector <node> G[21]; 9 const int INF = 1 << 30; 10 int n, m, k, e, d, D[101][101], f[101]; 11 bool sce[21][101]; 12 bool clo[21]; 13 14 void add(int A, int B, int C) { 15 node t1 = {B, C}, t2 = {A, C}; 16 G[A].push_back(t1), G[B].push_back(t2); 17 } 18 19 void init() { 20 scanf("%d%d%d%d", &n, &m, &k, &e); 21 for (int i = 1; i <= m; i++) G[i].clear(); 22 for (int i = 1; i <= e; i++) { 23 int x, y, z; 24 scanf("%d%d%d", &x, &y, &z); 25 add(x, y, z); 26 } 27 memset(sce, 0, sizeof(sce)); 28 scanf("%d", &d); 29 for (int i = 1; i <= d; i++) { 30 int p, a, b; scanf("%d%d%d", &p, &a, &b); 31 for (int j = a; j <= b; j++) 32 sce[p][j] = 1; 33 } 34 } 35 36 int SPFA() { 37 int head = 0, tail = 1, f[1000], dis[1000]; 38 bool b[21]; 39 memset(b, 0, sizeof(b)); 40 for (int i = 1; i <= m; i++) dis[i] = INF; 41 b[1] = 1, f[1] = 1, dis[1] = 0; 42 while (head < tail) { 43 int T = f[++head]; b[T] = 0; 44 for (int i = 0; i < G[T].size(); i++) 45 if (!clo[G[T][i].t]) 46 if (dis[T] + G[T][i].v < dis[G[T][i].t]) { 47 dis[G[T][i].t] = dis[T] + G[T][i].v; 48 if (!b[G[T][i].t]) { 49 b[G[T][i].t] = 1; f[++tail] = G[T][i].t; 50 } 51 } 52 } 53 return dis[m]; 54 } 55 56 int main() { 57 init(); 58 59 for (int i = 1; i <= n; i++) 60 for (int j = i; j <= n; j++) { 61 memset(clo, 0, sizeof(clo)); 62 for (int k = 1; k <= m; k++) 63 for (int l = i; l <= j; l++) 64 clo[k] = clo[k] || sce[k][l]; 65 D[i][j] = SPFA(); 66 } 67 f[0] = -k; 68 for (int i = 1; i <= n; i++) f[i] = INF; 69 70 for (int i = 1; i <= n; i++) 71 for (int j = 1; j <= i; j++) 72 if (D[j][i] != INF && f[j - 1] != INF) 73 if (f[j - 1] + D[j][i] * (i - j + 1) + k < f[i]) 74 f[i] = f[j - 1] + D[j][i] * (i - j + 1) + k; 75 printf("%d\n", f[n]); 76 return 0; 77 }
原文:http://www.cnblogs.com/VOHAHRV/p/4928882.html