Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define pub push_back
- #define ll long long
- #define mp make_pair
- #define all(a) a.begin(), a.end()
- #define x first
- #define y second
- const int INF = (int)1e9 + 7;
- const ll LINF = (ll)4e18 + 7;
- using namespace std;
- struct reb{
- int to, c, num;
- reb() {}
- reb(int x1, int y1, int c1){
- to = x1;
- c = y1;
- num = c1;
- }
- };
- const int dd = 1000007;
- int n, m;
- vector<reb> g[dd];
- vector<reb> gr[dd];
- vector<int> g2[dd];
- int d[2][dd];
- ll dp[dd];
- set<pair<int, int> > se;
- void relax1(int v){
- for (auto to : g[v]){
- if (d[0][to.to] > d[0][v] + to.c){
- se.erase(mp(d[0][to.to], to.to));
- d[0][to.to] = d[0][v] + to.c;
- se.insert(mp(d[0][to.to], to.to));
- }
- }
- }
- void dij1(){
- for (int i = 0; i < n; i++) d[0][i] = INF;
- d[0][0] = 0;
- se.insert(mp(d[0][0], 0));
- while(se.size()){
- auto now = *se.begin();
- se.erase(se.begin());
- relax1(now.y);
- }
- }
- void relax2(int v){
- for (auto to : gr[v]){
- if (d[1][to.to] > d[1][v] + to.c){
- se.erase(mp(d[1][to.to], to.to));
- d[1][to.to] = d[1][v] + to.c;
- se.insert(mp(d[1][to.to], to.to));
- }
- }
- }
- void dij2(){
- for (int i = 0; i < n; i++) d[1][i] = INF;
- d[1][n - 1] = 0;
- se.insert(mp(0, n - 1));
- while(se.size()){
- auto now = *se.begin();
- se.erase(se.begin());
- relax2(now.y);
- }
- }
- vector<pair<pair<int, int>, int> > re[dd];
- int kk = 0;
- vector<pair<int, int> > q[dd];
- vector<int> por;
- bool was[dd];
- vector<pair<int, int> > ha[dd];
- vector<pair<double, pair<ll, ll> > > t[dd];
- void dfs(int v){
- was[v] = 1;
- for (int to : g2[v])
- if (!was[to]) dfs(to);
- por.pub(v);
- }
- double per(pair<ll, ll> t, pair<ll, ll> s){
- return (double)(s.y - t.y) / (double)(t.x - s.x);
- }
- const bool is_testing = 1;
- int main(){
- srand('W' + 'I' + 'N');
- if (is_testing){
- freopen("trains.in", "r", stdin);
- freopen("trains.out", "w", stdout);
- } else {
- }
- scanf("%d %d", &n, &m);
- for (int i = 0; i < m; i++){
- int sz;
- scanf("%d", &sz);
- int last;
- scanf("%d", &last); last--;
- for (int j = 0; j < sz; j++){
- int vv, tt;
- scanf("%d %d", &tt, &vv);
- vv--;
- g[last].pub(reb(vv, tt, i));
- gr[vv].pub(reb(last, tt, i));
- re[i].pub(mp(mp(last, vv), tt));
- last = vv;
- }
- }
- dij1(); dij2();
- for (int i = 0; i < m; i++){
- bool f = 0;
- for (int j = (int)re[i].size() - 1; j >= 0; j--){
- int a = re[i][j].x.x, b = re[i][j].x.y, c = re[i][j].y;
- if (d[0][a] + c + d[1][b] == d[0][n - 1]){
- if (!f){
- kk++;
- q[kk].pub(mp(b, c));
- }
- f = 1;
- q[kk].pub(mp(a, c));
- } else f = 0;
- }
- }
- for (int i = 1; i <= kk; i++){
- reverse(all(q[i]));
- for (int j = (int)q[i].size() - 1; j >= 1; j--)
- q[i][j].y = q[i][j - 1].y;
- q[i][0].y = 0;
- for (int j = 1; j < q[i].size(); j++)
- q[i][j].y += q[i][j - 1].y;
- for (int j = 1; j < q[i].size(); j++)
- g2[q[i][j - 1].x].pub(q[i][j].x);
- for (int j = 0; j < q[i].size(); j++)
- ha[q[i][j].x].pub(mp(i, j));
- }
- dfs(0);
- for (int i = 0; i < n; i++) dp[i] = -LINF;
- dp[n - 1] = 0;
- for (int v : por){
- for (pair<int, int> x : ha[v]){
- if (t[x.x].size() > 0){
- int l = -1, r = t[x.x].size();
- while(l + 1 < r){
- int m = (l + r) >> 1;
- if (t[x.x][m].x > q[x.x][x.y].y)
- r = m;
- else
- l = m;
- }
- ll b = t[x.x][l].y.y;
- ll k = t[x.x][l].y.x;
- dp[v] = max(dp[v], b + (ll)k * q[x.x][x.y].y + (ll)q[x.x][x.y].y * q[x.x][x.y].y);
- }
- }
- for (pair<int, int> x : ha[v]){
- ll b = dp[v] + (ll)q[x.x][x.y].y * q[x.x][x.y].y, k = (ll)-2 * q[x.x][x.y].y;
- while(t[x.x].size()){
- double xx = per(mp(k, b), t[x.x].back().y);
- if (xx <= t[x.x].back().x) t[x.x].pop_back();
- else {
- t[x.x].push_back(mp(xx, mp(k, b)));
- break;
- }
- }
- if (t[x.x].size() == 0)
- t[x.x].pub(mp(0, mp(k, b)));
- }
- }
- cout << d[0][n - 1] << ' ' << dp[0];
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement