zoukankan      html  css  js  c++  java
  • BZOJ1880 [Sdoi2009]Elaxia的路线 【最短路 + dp】

    题目

    最近,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。 出出出格格格式式式::: 一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)。

    输出格式

    一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)

    输入样例

    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

    提示

    对于30%的数据,N ≤ 100;
    对于60%的数据,N ≤ 1000;
    对于100%的数据,N ≤ 1500,输入数据保证没有重边和自环。

    题解

    最后的路径为公共的最短路,所以我们先将第一对点的所有最短路边建成一个新的拓扑图
    然后就可以在新图上dp了
    (f[i])为第一对点走到(i)时的最大公共最短路长
    显然(f[i] = max{f[j] + edge.w})(j)(i)拓扑图中的前驱点且i-j这条边在第二对点的最短路上】

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
    using namespace std;
    const int maxn = 1505,maxm = 3000005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
    	return out * flag;
    }
    int h[maxn],ne = 2;
    struct EDGE{int from,to,nxt,w,f;}ed[maxm];
    inline void build(int u,int v,int w){
    	ed[ne] = (EDGE){u,v,h[u],w}; h[u] = ne++;
    	ed[ne] = (EDGE){v,u,h[v],w}; h[v] = ne++;
    }
    int n,m,S1,T1,S2,T2;
    int d[4][maxn],vis[maxn];
    struct node{int u,d;};
    inline bool operator <(const node& a,const node& b){return a.d > b.d;}
    priority_queue<node> q;
    void dijkstra(int S,int p){
    	for (int i = 1; i <= n; i++) d[p][i] = INF,vis[i] = false;
    	d[p][S] = 0;
    	node u;
    	q.push((node){S,d[p][S]});
    	while (!q.empty()){
    		u = q.top(); q.pop();
    		if (vis[u.u]) continue;
    		vis[u.u] = true;
    		Redge(u.u) if (!vis[to = ed[k].to] && d[p][to] > d[p][u.u] + ed[k].w){
    			d[p][to] = d[p][u.u] + ed[k].w;
    			q.push((node){to,d[p][to]});
    		}
    	}
    }
    int de[maxn],f[maxn];
    queue<int> Q;
    void solve(){
    	dijkstra(S1,0); dijkstra(T1,1);
    	dijkstra(S2,2); dijkstra(T2,3);
    	for (int k = 2; k < ne; k++)
    		if (d[0][ed[k].from] + ed[k].w + d[1][ed[k].to] == d[0][T1])
    			ed[k].f = true,de[ed[k].to]++;
    	Q.push(S1);
    	int u;
    	while (!Q.empty()){
    		u = Q.front(); Q.pop();
    		Redge(u) if (ed[k].f){
    			if (d[2][u] + ed[k].w + d[3][to = ed[k].to] == d[2][T2] || d[3][u] + ed[k].w + d[2][to = ed[k].to] == d[2][T2])
    				f[to] = max(f[to],f[u] + ed[k].w);
    			if (!(--de[to])) Q.push(to);
    		}
    	}
    	int ans = 0;
    	for (int i = 1; i <= n; i++) ans = max(ans,f[i]);
    	printf("%d
    ",ans);
    }
    int main(){
    	n = read(); m = read();
    	S1 = read(); T1 = read(); S2 = read(); T2 = read();
    	int a,b,w;
    	for (int i = 1; i <= m; i++){
    		a = read(); b = read(); w = read();
    		build(a,b,w);
    	}
    	solve();
    	return 0;
    }
    
    
  • 相关阅读:
    PHP连接FTP服务的简单实现
    Map遍历
    线程的互斥与同步
    Java中Collections.sort()排序详解
    Echarts的赋值,设置数据
    JSON和GSON的使用
    发送邮箱验证
    java中获取服务器的IP和端口
    一个题目涉及到的50个Sql语句
    JAVA面试题二
  • 原文地址:https://www.cnblogs.com/Mychael/p/8474300.html
Copyright © 2011-2022 走看看