QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#55107#2289. Jail or JoyrideMIT01#WA 3ms4660kbC++4.5kb2022-10-12 11:33:462022-10-12 11:33:48

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-10-12 11:33:48]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:4660kb
  • [2022-10-12 11:33:46]
  • 提交

answer

#include <bits/stdc++.h>
#define ll long long
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define vi vector<int>
#define pi pair<int, int>
#define maxn 305
#define mod 998244353
template<typename T> bool chkmin(T &a, T b){return (b < a) ? a = b, 1 : 0;}
template<typename T> bool chkmax(T &a, T b){return (b > a) ? a = b, 1 : 0;}
ll ksm(ll a, ll b) {if (b == 0) return 1; ll ns = ksm(a, b >> 1); ns = ns * ns % mod; if (b & 1) ns = ns * a % mod; return ns;}
using namespace std;
ll dis[maxn][maxn];
int reach[maxn][maxn][maxn]; // reach[a][b][c] : whether delete b to a edge can reach c
int canmove[maxn][maxn][maxn]; // whether [p][t][y] is valid in dp. 
int cnt[maxn][maxn];

ll dp[2][maxn][maxn]; // dp[0][p][t]: police to move, (p, t)
    // dp[1][p][t]: thief to move, (p, t), p is adjacent to t
    // dp[0][p][t] -> min_x(dp[1][x][t] + dis[p][x] + dis[x][t])
    // dp[1][p][t] -> max_y(dp[0][t][y], such that can move to y over y with max distance)
int eg[maxn][maxn];
int fa[maxn];
void initfa() {
    for (int i = 1; i < maxn; i++)
        fa[i] = i;
}
int gfa(int a) {
    if (fa[a] == a) return a;
    return fa[a] = gfa(fa[a]);
}
void lk(int u, int v) {
    fa[gfa(u)] = gfa(v);
}
int cfa[maxn];
int deg[maxn];

int main() {
    int n, m, p, t;
    cin >> n >> m >> p >> t;
    const ll inf = 1e18;
    for (int j = 0; j < maxn; j++)
        for (int k = 0; k < maxn; k++) 
            dp[0][j][k] = inf;
            
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            dis[i][j] = inf;
    for (int i = 1; i <= n; i++)
        dis[i][i] = 0;

    for (int i = 1; i <= m; i++) {
        int a, b, l;
        scanf("%d%d%d", &a, &b, &l);
        chkmin(dis[a][b], (ll)l);
        chkmin(dis[b][a], (ll)l);
        deg[a] += 1, deg[b] += 1;
        eg[a][b] = 1;
        eg[b][a] = 1;
    }
    for (int k = 1; k <= n; k++)
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                chkmin(dis[i][j], dis[i][k] + dis[k][j]);
    for (int d = 1; d <= n; d++) {
        initfa();
        for (int s = 1; s <= n; s++)
            for (int t = 1; t <= n; t++) {
                if (s == d || t == d) continue;
                if (!eg[s][t]) continue;
                lk(s, t);
            }
        for (int s = 1; s <= n; s++) {
            if (!eg[d][s]) continue;
            for (int j = 1; j <= n; j++)
                cfa[j] = fa[j];
            for (int t = 1; t <= n; t++)
                if (eg[d][t] && t != s)
                    lk(d, t);
            for (int j = 1; j <= n; j++)
                if (gfa(j) == gfa(d))
                    reach[d][s][j] = 1; // whether d can reach j without using (d,s)
            for (int j = 1; j <= n; j++)
                fa[j] = cfa[j];
        }
    }
    for (int p = 1; p <= n; p++)
        for (int j = 1; j <= n; j++) {
            ll mlen = 0;
            for (int k = 1; k <= n; k++)
                if (!reach[j][p][k]) continue;
                else chkmax(mlen, dis[j][k]);
            for (int k = 1; k <= n; k++)
                if (reach[j][p][k] && dis[j][k] == mlen)
                    canmove[p][j][k] = 1,  // (p, j) -> (j, k)
                    cnt[p][j] += 1;
        }
    #define ar3 array<int, 3>
    priority_queue<pair<ll, ar3> > q;
    for (int p = 1; p <= n; p++) {
        dp[0][p][p] = 0;
        q.push(mp(0, ar3{0, p, p}));
    }
    while (!q.empty()) {
        auto [d, a] = q.top(); q.pop();
        if (dp[a[0]][a[1]][a[2]] != -d) continue;
        if (a[0] == 1) {
            // (0,p,t) -> (1,x,t)
            int x = a[1], t = a[2];

            assert(eg[x][t]);
            for (int p = 1; p <= n; p++)
                if (chkmin(dp[0][p][t], dp[1][x][t] + dis[p][x] + dis[x][t]))
                    q.push(mp(-dp[0][p][t], ar3{0, p, t}));
        }
        else {
            int t = a[1], s = a[2];
            // (1, x, t) -> (0, t, s)
            for (int x = 1; x <= n; x++) {
                if (!eg[x][t]) continue;
                if (!canmove[x][t][s]) continue;
                cnt[x][t] -= 1;
                chkmax(dp[1][x][t], dp[0][t][s]);
                if (cnt[x][t] == 0)
                    q.push(mp(-dp[1][x][t], ar3{1, x, t}));
            }
        }
    }
    ll ans = dp[0][p][t];
    if (ans > inf / 2) cout << "impossible" << endl;
    else cout << ans << endl;
    
    return 0;
}
/*
5 5 1 2
1 2 25 5 1 2
1 2 2
2 3 2
3 4 3
4 5 1
2 5 2
2 3 2
3 4 3
4 5 1
2 5 2
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 3ms
memory: 4660kb

input:

9 10 1 2
1 2 225869
2 3 1772
3 4 314393
4 5 692250
5 6 684107
4 6 532792
3 7 441133
7 8 468183
8 9 186297
7 9 228792

output:

455282

result:

wrong answer 1st lines differ - expected: 'impossible', found: '455282'