제출 #1161699

#제출 시각아이디문제언어결과실행 시간메모리
1161699tw20000807Robot (JOI21_ho_t4)C++20
34 / 100
3096 ms67408 KiB
#include<bits/stdc++.h>
#define int long long
#define all(v) v.begin(), v.end()
#define SZ(x) (int)x.size()
#define pii pair<int, int>
#define X first
#define Y second

using namespace std;
const int maxn = 2e5 + 10;
const int mod = 1e9 + 7;//    998244353;
const int llmx = 1e18;


void sol(){
    int n, m;
    cin >> n >> m;
    vector< vector< array<int, 3> > > g(n + 1);
    vector< map<int, int> > cnt(n + 1);

    vector< int > dis(2 * m + n + 1, llmx);
    vector< vector< pii > > num(n + 1);
    vector< int > base(n + 1);
    while(m--){
        int a, b, c, p;
        cin >> a >> b >> c >> p;
        cnt[a][c] += p;
        cnt[b][c] += p;
        num[a].push_back({p, c});
        num[b].push_back({p, c});

        g[a].push_back({b, c, p});
        g[b].push_back({a, c, p});
    }
    for(int i = 1; i <= n; ++i){
        num[i].push_back({0, 0});
        sort(all(num[i]));
        num[i].resize(unique(all(num[i])) - num[i].begin());
        base[i] = base[i - 1] + SZ(num[i - 1]);
    }
    auto get = [&](int id, int p, int c) -> int {
        return base[id] + lower_bound(all(num[id]), pii(p, c)) - num[id].begin();
    };

    priority_queue< array<int, 4>, vector< array<int, 4> >, greater< array<int, 4> > > pq;

    dis[get(1, 0, 0)] = 0;
    pq.push({0, 1, 0, 0}); 

    while(!pq.empty()){
        auto [D, cur, cost, col] = pq.top(); pq.pop();
        if(dis[get(cur, cost, col)] != D) continue;

        for(auto &[nxt, c, p] : g[cur]){
            int id1 = get(nxt, p, c);
            int id2 = get(nxt, 0, 0);

            if(dis[id1] > D + p){
                dis[id1] = D + p;
                pq.push({dis[id1], nxt, p, c});
            }
            if(dis[id2] > D + max(0LL, cnt[cur][c] - p - (c == col ? cost : 0))){
                dis[id2] = D + max(0LL, cnt[cur][c] - p - (c == col ? cost : 0));
                pq.push({dis[id2], nxt, 0, 0});
            }
        }
    }
    int ans = dis[get(n, 0, 0)];
    for(auto &[nxt, c, p] : g[n]){
        ans = min(ans, dis[get(n, p, c)]);
    }
    if(ans == llmx) ans = -1;
    cout << ans << "\n";
}
/*
4 6
1 4 4 4
3 4 1 3
1 3 4 4
2 4 3 1
2 3 3 2
1 2 4 2

// 3

5 2
1 4 1 2
3 5 1 4
// -1


5 7
2 3 7 1
1 4 5 1
4 5 3 1
3 4 7 1
2 4 3 1
3 5 6 1
1 2 5 1
// 1

13 21
7 10 4 4
3 6 4 7
8 10 4 5
3 9 2 5
1 4 4 5
2 6 4 2
3 11 2 2
3 8 16 2
8 11 16 1
6 10 4 14
6 8 16 6
9 12 16 5
5 13 4 6
1 12 4 7
2 4 4 18
2 9 4 10
2 12 4 6
10 13 4 28
5 7 2 5
5 11 2 16
7 13 4 20

// 7


*/
signed main(){
    ios::sync_with_stdio(0), cin.tie(0), cerr.tie(0);
    int t = 1; //cin >> t;
    while(t--) sol();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...