Question: an undirected graph. Some of the sides are normal roads and some are railways. I would like to ask how many railways can be deleted so that all the points can be reached to the capital (numbered 1).
Idea: Find the number of railway lines that cannot be deleted. The answer is to lose the total number. First, find the shortest path from the capital to all points. After finding the shortest path, enumerate all points except the capital. If the updated Edge contains only railways, A railway cannot be deleted.
Note: the shortest path is obtained here. spfa is used at the first 10th point of TLE, and finally changed to Dijkstra with heap optimization.
#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#include <iostream>#include<queue>#define M 1000010#define N 100050#define LL __int64#define INF (1000000000000000LL)using namespace std;struct node { int to, nx, va, flag;} e[M];int head[N], ecnt;struct info { int id, va;};bool operator<(info a, info b) { return a.va > b.va;}priority_queue<info> q;void addedge(int x, int y, int va, int flag) { e[ecnt].to = y; e[ecnt].va = va; e[ecnt].nx = head[x]; e[ecnt].flag = flag; head[x] = ecnt++;}bool bo[N];LL d[N];int n, m, k;void Dij() { for (int i = 0; i <= n; ++i) d[i] = INF; memset(bo, 0, sizeof(bo)); d[1] = 0; int st = 0, ed = 0; while (!q.empty()) q.pop(); info a; a.va = 0; a.id = 1; q.push(a); while (!q.empty()) { a = q.top(); q.pop(); int now = a.id; if (bo[now]) continue; bo[now] = true; for (int j = head[now]; j != -1; j = e[j].nx) { int u = e[j].to; if (d[u] > d[now] + e[j].va) { d[u] = d[now] + e[j].va; a.id=u; a.va=d[u]; q.push(a); } } }}void init() { scanf("%d%d%d", &n, &m, &k); memset(head, -1, sizeof(head)); ecnt = 0; for (int i = 0; i < m; ++i) { int x, y, z; scanf("%d%d%d", &x, &y, &z); addedge(x, y, z, 0); addedge(y, x, z, 0); } for (int i = 0; i < k; ++i) { int x, y; scanf("%d%d", &x, &y); addedge(1, x, y, 1); addedge(x, 1, y, 1); }}void solve() { Dij(); int ans = k; for (int i = 2; i <= n; ++i) { int flag = 0, flag1 = 0; for (int j = head[i]; j != -1; j = e[j].nx) { int u = e[j].to; if (d[u] + e[j].va == d[i]) { if (e[j].flag == 1) flag = 1; else flag1 = 1; } } if (flag == 1 && flag1 == 0) ans--; } printf("%d\n", ans);}int main() { init(); solve();}
View code