题意:给一个带权无向图和源点s,问删掉一个点,最多能使多少个点的最短路变大(从s出发)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define N (200050)
#define M (1000010)
#define inf 0x3f3f3f3f
#define eps 1e-4
#define LL long long
#define pii pair<int, int>
#define MP make_pair
#define ls (i<<1)
#define rs (i<<1|1)
#define md (ll+rr>>1)
#define lson ll, md, ls
#define rson md+1, rr, rs
#define mod 1000000007
int fst[N], vv[M], nxt[M], cost[M], e;
LL dis[N];
int ans[N];
void init() {
memset(fst, -1, sizeof fst);
e = 0;
}
void add(int u,int v, int w) {
vv[e] = v, cost[e] = w, nxt[e] = fst[u], fst[u] = e++;
}
vector<int> g[N], rg[N], bucket[N], T[N];
int sdom[N], par[N], dom[N], fa[N], lab[N];
int tid[N], rev[N], dfn;
void dfs(int u) {
tid[u] = ++dfn;
rev[dfn] = u;
lab[dfn] = dfn;
sdom[dfn] = dfn;
fa[dfn] = dfn;
for(int i = 0; i < g[u].size(); ++i) {
int v = g[u][i];
if(!tid[v]) {
dfs(v);
par[tid[v]] = tid[u];
}
rg[tid[v]].push_back(tid[u]);
}
}
int find(int u, int x = 0) {
if(u == fa[u]) return x ? -1 : u;
int v = find(fa[u], x+1);
if(v < 0) return u;
if(sdom[lab[fa[u]]] < sdom[lab[u]])
lab[u] = lab[fa[u]];
fa[u] = v;
return x ? v : lab[u];
}
void Union(int u,int v) {
fa[v] = u;
}
void Dom(int n, int s) {
dfs(s);
for(int i = n; i >= 1; --i) {
for(int j = 0; j < rg[i].size(); ++j) {
int v = rg[i][j];
sdom[i] = min(sdom[i], sdom[find(v)]);
}
if(i > 1) bucket[sdom[i]].push_back(i);
for(int j = 0; j < bucket[i].size(); ++j) {
int w = bucket[i][j], v = find(w);
if(sdom[v] == sdom[w]) dom[w] = sdom[w];
else dom[w] = v;
}
if(i > 1) Union(par[i], i);
}
for(int i = 2; i <= n; ++i) {
if(dom[i] != sdom[i]) dom[i] = dom[dom[i]];
T[rev[i]].push_back(rev[dom[i]]);
T[rev[dom[i]]].push_back(rev[i]);
}
}
void spfa(int s) {
queue<int> que;
static bool vis[N];
memset(vis, 0, sizeof vis);
for(int i = 0; i < N; ++i) dis[i] = 1e16;
dis[s] = 0;
vis[s] = 1;
que.push(s);
while(!que.empty()) {
int u = que.front();
que.pop();
vis[u] = 0;
for(int i = fst[u]; ~i; i = nxt[i]) {
int v = vv[i];
if(dis[v] > dis[u] + cost[i]) {
dis[v] = dis[u] + cost[i];
if(!vis[v]) que.push(v), vis[v] = 1;
}
}
}
memset(vis, 0, sizeof vis);
vis[s] = 1;
que.push(s);
while(!que.empty()) {
int u = que.front();
que.pop();
for(int i = fst[u]; ~i; i = nxt[i]) {
int v = vv[i];
if(dis[v] == dis[u] + cost[i]) {
g[u].push_back(v);
if(!vis[v]) vis[v] = 1, que.push(v);
}
}
}
}
void gao(int u, int p) {
ans[u] = 1;
for(int i = 0; i < T[u].size(); ++i) {
int v = T[u][i];
if(v == p) continue;
gao(v, u);
ans[u] += ans[v];
}
}
int main() {
int n, m, s;
scanf("%d%d%d", &n, &m, &s);
init();
for(int i = 0; i < m; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
spfa(s);
Dom(n, s);
gao(s, -1);
int mx = 0;
for(int i = 1; i <= n; ++i) if(i != s)
mx = max(ans[i], mx);
printf("%d\n", mx);
}