正反两次最短路用于判断边是不是最短路上的边,把最短路径上的边取出来。然后求割边。
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define fi first #define se second #define bug(x) cout<<#x<<‘=‘<<x<<endl; #define FOR(i,s,e) for(int i = s; i < e; i++) const int maxn = 2e4+5; const int maxe = 2e5+10; ll d1[maxn],d2[maxn]; struct Graph { int head[maxn],fro[maxe],to[maxe],nxt[maxe],ecnt; ll w[maxe]; void init() { memset(head,-1,sizeof(head)); ecnt = 0; } Graph(){ init(); } void addEdge(int u,int v,ll l) { fro[ecnt] = u; to[ecnt] = v; w[ecnt] = l; nxt[ecnt] = head[u]; head[u] = ecnt++; } }G1,G3; int id[maxe]; const ll INF = 0x3f3f3f3f3f3f3f3fLL; int cut[maxe]; // 0 not shortest path 1 shortest path 2 unique shortest path int dfs_clock,dfn[maxn],low[maxn]; void Tarjan(int u,int fa) { dfn[u] = low[u] = ++dfs_clock; for(int i = G3.head[u]; ~i; i = G3.nxt[i]){ if((i^1) == fa) continue; int v = G3.to[i]; if(!dfn[v]){ Tarjan(v,i); low[u] = min(low[u],low[v]); if(low[v]>dfn[u]) { cut[id[i]] = 1; } }else { low[u] = min(low[u],low[v]); } } } struct Node { ll d; int u; bool operator < (const Node& x) const{ return d > x.d; } }; bool vis[maxn]; void Dijkstra(int s,Graph &g,ll (&d)[maxn]) { memset(vis,0,sizeof(vis)); priority_queue<Node> q; memset(d,0x3f,sizeof(d)); d[s] = 0; q.push(Node{0,s}); while(q.size()){ Node x = q.top(); q.pop(); int u = x.u; if(vis[u]) continue; vis[u] = true; for(int i = g.head[u]; ~i; i = g.nxt[i] ){ int v = g.to[i]; if(v == u) continue; if(d[v]> d[u]+g.w[i]){ d[v] = d[u]+g.w[i]; q.push(Node{d[v],v}); } } } } vector<int> ans; bool evis[maxe]; int main() { freopen("important.in","r",stdin); freopen("important.out","w",stdout); int n,m,s,t; scanf("%d%d",&n,&m); s = 1; t = n; for(int i = 0; i < m; i++){ int u,v,l; scanf("%d%d%d",&u,&v,&l); G1.addEdge(u,v,l); G1.addEdge(v,u,l); } Dijkstra(s,G1,d1); Dijkstra(t,G1,d2); ll shortest = d1[t]; for(int i = 0,M = m*2; i < M; i++){ int u = G1.fro[i], v = G1.to[i]; if(shortest == G1.w[i] + d1[u] + d2[v] ){ int eid = i/2; if(!evis[eid]){ evis[eid] = true; id[G3.ecnt] = eid; G3.addEdge(u,v,G1.w[i]); id[G3.ecnt] = eid; G3.addEdge(v,u,G1.w[i]); } } } Tarjan(s,-1); for(int i = 0; i < m; i ++){ if(cut[i]) ans.push_back(i+1); } int sz = ans.size(); printf("%d\n",sz); for(int i = 0; i < sz; i++){ printf("%d%c",ans[i],i == sz?‘\n‘:‘ ‘); } return 0; }
时间: 2024-10-12 04:44:43