QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#55106#2289. Jail or JoyrideMIT01#Compile Error//C++4.5kb2022-10-12 11:33:232022-10-12 11:33:25

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:25]
  • 评测
  • [2022-10-12 11:33:23]
  • 提交

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)
            assert(eg[x][t]);
            int x = a[1], t = a[2];
            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

In file included from /usr/include/c++/11/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h:33,
                 from answer.code:1:
answer.code: In function ‘int main()’:
answer.code:111:23: error: ‘x’ was not declared in this scope
  111 |             assert(eg[x][t]);
      |                       ^
answer.code:56:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   56 |         scanf("%d%d%d", &a, &b, &l);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~