链接:
http://codeforces.com/contest/853/problem/B
题意:
有n+1个国家,标号为0-n,现在1-n国家都有一个人要到0国家并且返回,要求1-n国家的人必须同时在0国家k天,
现在有m个航班,问所需的字少花费,无法满足条件为-1
题解:
用两个数组,come和back,come[i]表示在第i天全部到达所需要的最少花费,back[i]同理,如果无法全部到达,为INF,所以最后的结果就是
ans = min(ans, come[i] + back[i + k + 1]);
代码:
31 struct Node { 32 int d, id, cost; 33 bool operator<(const Node &t) { 34 return d < t.d; 35 } 36 }; 37 38 int n, m, k; 39 vector<Node> C; 40 vector<Node> B; 41 int vis[MAXN]; 42 ll come[MAXN * 10]; 43 ll back[MAXN * 10]; 44 45 int main() { 46 ios::sync_with_stdio(false), cin.tie(0); 47 cin >> n >> m >> k; 48 while (m--) { 49 int a, b, c, d; 50 cin >> a >> b >> c >> d; 51 if (c == 0) C.pb(Node{ a,b,d }); 52 else B.pb(Node{ a,c,d }); 53 } 54 sort(all(C)); 55 sort(all(B)); 56 set<int> S; 57 ll sum = 0; 58 rep(i, 0, MAXN * 10) come[i] = back[i] = 1e18; 59 rep(i, 0, C.size()) { 60 Node t = C[i]; 61 if (vis[t.id] == 0) { 62 vis[t.id] = t.cost; 63 sum += t.cost; 64 S.insert(t.id); 65 } 66 else { 67 if (t.cost < vis[t.id]) { 68 sum -= vis[t.id]; 69 vis[t.id] = t.cost; 70 sum += t.cost; 71 } 72 } 73 if (S.size() == n) come[t.d] = min(come[t.d], sum); 74 } 75 if (S.size() != n) return (cout << -1 << endl), 0; 76 77 S.clear(); 78 sum = 0; 79 memset(vis, 0, sizeof(vis)); 80 per(i, 0, B.size()) { 81 Node t = B[i]; 82 if (vis[t.id] == 0) { 83 vis[t.id] = t.cost; 84 sum += t.cost; 85 S.insert(t.id); 86 } 87 else { 88 if (t.cost < vis[t.id]) { 89 sum -= vis[t.id]; 90 vis[t.id] = t.cost; 91 sum += t.cost; 92 } 93 } 94 if (S.size() == n) back[t.d] = (back[t.d], sum); 95 } 96 if (S.size() != n) return (cout << -1 << endl), 0; 97 98 rep(i, 1, MAXN * 10) come[i] = min(come[i], come[i - 1]); 99 per(i, 0, MAXN * 10 - 1) back[i] = min(back[i], back[i + 1]); 100 ll ans = 1e18; 101 rep(i, 1, MAXN * 10 - k - 1) ans = min(ans, come[i] + back[i + k + 1]); 102 if (ans == 1e18) ans = -1; 103 cout << ans << endl; 104 return 0; 105 }