求最短路径覆盖的全部边权值和。
思路:分别从起点和终点两次求最短路,再比较两个点到起点的距离和他们之间的权值相加和是否等于最短路径。
这题很好
1 #include <cstring> 2 #include <cmath> 3 #include <queue> 4 #include <vector> 5 #include <cstdio> 6 #include <algorithm> 7 using namespace std; 8 typedef long long ll; 9 const int maxn = 10005; 10 const int maxm = 600000; 11 const int INF = 0x3f3f3f3f; 12 int n, m; 13 struct ee { 14 int to; 15 int nxt; 16 int w; 17 } edge[maxm]; 18 19 int head[maxn], tol; 20 void init() { 21 memset(head, -1, sizeof head ); 22 tol = 0; 23 } 24 void add(int u, int v, int w) { 25 edge[tol].to = v; 26 edge[tol].w = w; 27 edge[tol].nxt = head[u]; 28 head[u] = tol++; 29 } 30 int d1[maxn], d2[maxn]; 31 bool vis[maxn]; 32 void spfa(int s, int t, int d[]) { 33 for(int i=0; i<n; ++i) d[i] = INF; 34 memset(vis, false, sizeof vis ); 35 queue<int> q; 36 q.push(s); 37 d[s] = 0; 38 vis[s] = true; 39 while(!q.empty()) { 40 int u = q.front(); 41 q.pop(); 42 vis[u] = false; 43 for(int i=head[u]; ~i; i=edge[i].nxt) { 44 int &v = edge[i].to; 45 int &cost = edge[i].w; 46 if(d[v] > d[u] + cost) { 47 d[v] = d[u] + cost; 48 if(!vis[v]) { 49 vis[v] = true; 50 q.push(v); 51 } 52 } 53 } 54 } 55 } 56 void solve() { 57 int s = 0, t = n-1; 58 spfa(s, t, d1); 59 spfa(t, s, d2); 60 ll ans = 0; 61 int minn = d1[t]; 62 for(int u=0; u<n; u++) { 63 for(int i=head[u]; ~i; i=edge[i].nxt) { 64 int &v=edge[i].to; 65 int &cost=edge[i].w; 66 if(d1[u]+d2[v]+cost==minn) { 67 ans+=cost; 68 } 69 } 70 } 71 printf("%I64d\n", ans*2); 72 } 73 int main() { 74 int u, v, l; 75 while(~scanf("%d%d", &n, &m)) { 76 init(); 77 for(int i=0; i<m; ++i) { 78 scanf("%d%d%d", &u, &v, &l); 79 add(u, v, l); 80 add(v, u, l); 81 } 82 solve(); 83 } 84 return 0; 85 }
时间: 2024-11-05 15:05:10