列表

详情


NC20323. [SDOI2009]ELAXIA的路线

描述

最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们必须合理地安排两个人在一起的时间。
Elaxia和w**每天都要奔波于宿舍和实验室之间,他们希望在节约时间的前提下,一起走的时间尽可能的长。 
现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 
具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

输入描述

第一行:两个整数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;
}

上一题