NC20323. [SDOI2009]ELAXIA的路线
描述
输入描述
第一行:两个整数N和M(含义如题目描述)。第二行:四个整数x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ ≤ N),分别表示Elaxia的宿舍和实验室及w**的宿舍和实验室的标号(两对点分别 x1,y1和x2,y2)。接下来M行:每行三个整数,u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之间有一条路,经过这条路所需要的时间为l。
输出描述
一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)
示例1
输入:
9 10 1 6 7 8 1 2 1 2 5 2 2 3 3 3 4 2 3 9 5 4 5 3 4 6 4 4 7 2 5 8 1 7 9 1
输出:
3
C++14(g++5.4) 解法, 执行用时: 308ms, 内存消耗: 12828K, 提交时间: 2020-02-14 20:58:51
#include<bits/stdc++.h> #define N 2005 #define M 1000007 #define inf 0x3f3f3f3f using namespace std; struct node{ int u,v,w,nxt,f; }e[M<<1],E[M<<1]; queue<int>q; int n,m,cnt,cnt2; int head[N],p[5],d[5][N],Head[N]; int in[N],f[N],v[N]; void add(int u,int v,int w) { e[++cnt].u=u;e[cnt].v=v;e[cnt].w=w; e[cnt].nxt=head[u]; head[u]=cnt; } void add_(int u,int v,int w) { E[++cnt2].u=u;E[cnt2].v=v;E[cnt2].w=w; E[cnt2].nxt=Head[u]; Head[u]=cnt2; } void spfa(int x) { memset(v,0,sizeof v); for(int i=1;i<=n;++i) if(i!=p[x]) d[x][i]=inf; q.push(p[x]);v[p[x]]=1; while(!q.empty()) { int now=q.front();q.pop();v[now]=0; for(int i=head[now];i;i=e[i].nxt) { int to=e[i].v; if(d[x][to]>d[x][now]+e[i].w) { d[x][to]=d[x][now]+e[i].w; if(!v[to]) v[to]=1,q.push(to); } } } } void rebuild() { for(int i=1;i<=cnt;++i) if(d[1][e[i].u]+e[i].w+d[2][e[i].v]==d[1][p[2]]) { add_(e[i].u,e[i].v,e[i].w); if(d[3][e[i].u]+e[i].w+d[4][e[i].v]==d[3][p[4]] || d[4][e[i].u]+e[i].w+d[3][e[i].v]==d[3][p[4]]) E[cnt2].f=1; in[e[i].v]++; } } void Tsort() { while(!q.empty()) q.pop(); q.push(p[1]); int now; while(!q.empty()) { now=q.front(); q.pop(); for(int i=Head[now];i;i=E[i].nxt) { --in[E[i].v]; if(!in[E[i].v]) { q.push(E[i].v); f[E[i].v]=max(f[E[i].v],f[now]+E[i].w*E[i].f); } } } } int main() { int x,y,z; scanf("%d%d",&n,&m); for(int i=1;i<=4;++i) scanf("%d",&p[i]); for(int i=1;i<=m;++i) { scanf("%d%d%d",&x,&y,&z); add(x,y,z),add(y,x,z); } for(int i=1;i<=4;++i) spfa(i); rebuild(); Tsort(); printf("%d",f[p[2]]); return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 191ms, 内存消耗: 68832K, 提交时间: 2020-05-08 09:30:04
#include<bits/stdc++.h> typedef long long ll; using namespace std; #define pb push_back const int maxn = 1e6 + 10; const int inf = 0x3f3f3f3f; struct node{ int v, w, id; }; vector<node> e[maxn]; bool evis[maxn], vis[maxn]; ll dis[3][maxn]; ll dp[maxn]; void bfs(int x, int y){ priority_queue<pair<ll, int> > q; memset(dis[y], 0x3f, sizeof(dis[y])); memset(vis, 0, sizeof(vis)); memset(dp, 0, sizeof(dp)); q.push({ 0, x }); dis[y][x] = 0; dp[x] = 0; while (!q.empty()){ x = q.top().second; q.pop(); if (vis[x])continue; vis[x] = 1; for (auto it : e[x]){ int v = it.v; int w = it.w; int id = it.id; if (dis[y][v] > dis[y][x] + w){ dis[y][v] = dis[y][x] + w; dp[v] = dp[x] + w*evis[id]; q.push({ -dis[y][v], v }); } else if (dis[y][v] == dis[y][x] + w) dp[v] = max(dp[v], dp[x] + w*evis[id]); } } } int main(){ int n, m; scanf("%d%d", &n, &m); int a, b, c, d; scanf("%d%d%d%d", &a, &b, &c, &d); for (int i = 1; i <= m; i++){ int u, v, w; scanf("%d%d%d", &u, &v, &w); e[u].pb({ v, w, i }); e[v].pb({ u, w, i }); } bfs(a, 0); bfs(b, 2); for (int i = 1; i <= n; i++){ for (auto it : e[i]){ int u = i, v = it.v, w = it.w, id = it.id; if (dis[0][u] + dis[2][v] + w == dis[0][b]) evis[id] = 1; if (dis[0][v] + dis[2][u] + w == dis[0][b]) evis[id] = 1; } } bfs(c, 1); cout << dp[d] << endl; return 0; }