Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 7834 | Accepted: 3753 |
Description
Input
Output
Sample Input
4 2 1 1 3 10 2 4 20 2 3 3
Sample Output
27
求牛1-N 其实最最大距离就是1-N的满足条件的最短路
由最短路性质可知 对于所有的边(u, v) 均有d[u] + cost[u][v] >= d[v]
那么由题目已知 必须顺序排序 但是可以多牛共存一点
即 d[i+1] >= d[i] → d[i+1] + 0 >= d[i] (从i+1连一条权为0的边到i)
喜欢的牛 B - A <= D → A + D >= B (从A连一条权为D的边到B)
讨厌的牛 B - A >= D → B - D >= A (从B连一条权为-D的边到A)
由于存在负权 我们可以用Bellman-Ford来算最短路 O(EV)的复杂度题目规模完全够
AC代码如下:
// // POJ 3169 Layout // // Created by TaoSama on 2015-03-20 // Copyright (c) 2015 TaoSama. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> #define CLR(x,y) memset(x, y, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 1e5 + 10; int n, l, d, dp[1005]; struct Edge { int to, cost; }; vector<Edge> G[21005]; int BellmanFord() { memset(dp, 0x3f, sizeof dp); dp[1] = 0; for(int k = 1; k <= n; ++k) { for(int i = 1; i <= n; ++i) { for(int j = 0; j < G[i].size(); ++j) { Edge &e = G[i][j]; dp[e.to] = min(dp[e.to], dp[i] + e.cost); //printf("dp[%d]: %d\n",e.to, dp[e.to]); } } } return dp[n]; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); scanf("%d%d%d", &n, &l, &d); int a, b, c; for(int i = 1; i < n; ++i) G[i + 1].push_back((Edge) {i, 0}); for(int i = 1; i <= l; ++i) { scanf("%d%d%d", &a, &b, &c); G[a].push_back((Edge) {b, c}); } for(int i = 1; i <= d; ++i) { scanf("%d%d%d", &a, &b, &c); G[b].push_back((Edge) {a, -c}); } int ans = BellmanFord(); if(dp[1] < 0) ans = -1; else if(ans == INF) ans = -2; printf("%d\n", ans); return 0; }