求调 G
  • 板块学术版
  • 楼主VitrelosTia
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/12 22:02
  • 上次更新2024/10/13 09:04:27
查看原帖
求调 G
672333
VitrelosTia楼主2024/10/12 22:02
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;

const int N = 5e5 + 5;
int n, m;
map <pii, pii> id; 
struct edge { int u, v, w; } edg[N];

struct Graph {
    struct Edge { int to, nxt, w; } e[N << 1];
    int cur, head[N];
    void Add(int u, int v, int w) { e[++cur] = {v, head[u], w}; head[u] = cur; }
} g1, g2;
#define GoEdge(g, i, u, v) for (int v, w, i = g.head[u]; v = g.e[i].to, w = g.e[i].w, i; i = g.e[i].nxt)

struct Node {
    int u, dis;
    bool operator < (const Node &x) const { return dis > x.dis; }
}; priority_queue <Node> q;
int dis[2][N]; vector <int> pre[N]; bool vis[N], tv[N], te[N];
void dij(int s, bool o) {
//  printf ("s = %d\n", s);
    memset(vis, false, sizeof vis); memset(dis[o], 0x3f, sizeof dis[o]);
    dis[o][s] = 0, q.push({s, 0});
    while (!q.empty()) {
        int u = q.top().u; q.pop();
//      printf ("u = %d\n", u);
        if (vis[u]) continue; vis[u] = true;
        GoEdge(g1, i, u, v) if (dis[o][v] > dis[o][u] + w)
            dis[o][v] = dis[o][u] + w, q.push({v, dis[o][v]});
    }
//  for (int u = 1; u <= n; u++) for (int v : pre[u])
//      tv[v] = true, te[id[{v, u}]] = true;
}
bool tree[N];

int idx, dfn[N], low[N]; int top, stk[N];
int cnt, bel[N];
void tarjan(int u, int ine) {
    dfn[u] = low[u] = ++idx; stk[++top] = u;
    GoEdge(g2, i, u, v) {
        if (!dfn[v]) {
            tarjan(v, i);
            low[u] = min(low[u], low[v]);
        }
        else if (i != (ine ^ 1)) low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {
        cnt++;
        while (true) {
            int v = stk[top--];
            bel[v] = cnt;
            if (u == v) break;
        }
    }
}

int main() {
//  ios::sync_with_stdio(false); cin.tie(nullptr);
//  freopen("ex_data.in", "r", stdin);
    cin >> n >> m;
    for (int i = 1, u, v, w; i <= m; i++) {
        cin >> u >> v >> w; // if (id[{u, v}]) continue;
        edg[2 * i - 1] = {u, v, w}, edg[2 * i] = {v, u, w};
        g1.Add(u, v, w); g1.Add(v, u, w);
        if (w < id[{u, v}].second || !id[{u, v}].second) id[{u, v}] = id[{v, u}] = {i, w};
    }
    dij(1, 0); dij(n, 1); g2.cur = 1;
//  for (int i = 1; i <= n; i++) cout << dis[0][i] << ' ' << dis[1][i] << '\n';
    for (int i = 1, u, v, w; u = edg[i].u, v = edg[i].v, w = edg[i].w, i <= 2 * m; i++)
        if (dis[0][u] + w + dis[1][v] == dis[0][n]) {
            g2.Add(u, v, 0), g2.Add(v, u, 0), tree[i] = true;
            // printf ("i = %d, u = %d, v = %d\n", i, u, v);
        }
    tarjan(1, 0);
    set <int> ans;
    for (int i = 1, u, v; u = edg[i].u, v = edg[i].v, i <= 2 * m; i++) 
        if (tree[i] && bel[u] != bel[v]) ans.insert(id[{u, v}].first);
    for (int i = 1; i <= m; i++) cout << (ans.count(i) ? "Yes\n" : "No\n");
    return 0;
}
2024/10/12 22:02
加载中...