题目描述

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

解法

对于以四个点为起点,跑四边最短路,重新建图,跑拓扑排序+DP

ac代码

# include <bits/stdc++.h>
# define LL long long
# define ms(a,b) memset(a,b,sizeof(a))
# define ri (register int)
# define inf 0x3f3f3f3f
# define pb push_back
# define dd double
# define fi first
# define se second
# define pii pair<int,int>
# define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
inline int gi(){
    int w=0,x=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return w?-x:x;
}
# define M 500005
# define N 1505
struct edge{
    int u,to,nt,w;
}E[M<<1],E1[M<<1];
int H[N],H1[N],dist[10][N],a[N],ind[N],ans[N];
bool vis[N];
int n,m,cnt,cnt1,res;
void addedge(int u,int v,int w){
    E[++cnt]=(edge){u,v,H[u],w}; H[u]=cnt;
}
void addedge_1(int u,int v,int w){
    if (dist[1][u]>dist[1][v]) swap(u,v);
    E1[++cnt1]=(edge){u,v,H1[u],w}; H1[u]=cnt1; ind[v]++;
}
void spfa(int id){
    queue<int>q;
    while (!q.empty()) q.pop();
    ms(vis,0);
    dist[id][a[id]]=0;
    q.push(a[id]);
    while (!q.empty()){
        int u=q.front(); q.pop(); vis[u]=0;
        for (int e=H[u];e;e=E[e].nt){
            int v=E[e].to;
            if (dist[id][v]>dist[id][u]+E[e].w){
                dist[id][v]=dist[id][u]+E[e].w;
                if (!vis[v]) vis[v]=1,q.push(v);
            }
        }
    }
}
void topo(){
    queue<int>q1; while (!q1.empty()) q1.pop();
    for (int i=1;i<=n;i++) if (!ind[i]) q1.push(i);
    while (!q1.empty()){
        int u=q1.front(); q1.pop();
        for (int e=H1[u];e;e=E1[e].nt){
            int v=E1[e].to; ind[v]--;
            ans[v]=max(ans[v],ans[u]+E1[e].w);
            res=max(res,ans[v]);
            if (!ind[v]) q1.push(v);
        }
    }
}
int main(){
    n=gi(),m=gi(); ms(dist,inf);
    for (int i=1;i<=4;i++) a[i]=gi();
    for (int i=1;i<=m;i++){
        int u=gi(),v=gi(),w=gi();
        addedge(u,v,w); addedge(v,u,w);
    }
    for (int i=1;i<=4;i++) spfa(i);
    for (int i=1;i<=cnt;i+=2){
        int u=E[i].u,v=E[i].to;
        if((dist[1][u]+E[i].w+dist[2][v]==dist[1][a[2]]||dist[1][v]+E[i].w+dist[2][u]==dist[1][a[2]])&&(dist[3][u]+E[i].w+dist[4][v]==dist[3][a[4]]||dist[3][v]+E[i].w+dist[4][u]==dist[3][a[4]])) addedge_1(u,v,E[i].w);
    }
    topo();
    printf("%d\n",res);
    return 0;
}

[luogu2149][bzoj1880][SDOI2009]Elaxia的路线【拓扑排序+最短路+DP】的更多相关文章

  1. bzoj1880: [Sdoi2009]Elaxia的路线(spfa,拓扑排序最长路)

    1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1944  Solved: 759[Submit][St ...

  2. BZOJ1880: [Sdoi2009]Elaxia的路线(最短路)

    1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2049  Solved: 805 题目链接:https ...

  3. BZOJ1880:[SDOI2009]Elaxia的路线(最短路,拓扑排序)

    Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间, ...

  4. BZOJ1880: [Sdoi2009]Elaxia的路线

    题意:求最短路最长公共距离. 考虑每一条边,如果满足dis(s1,u)+len+dis(v,t1)==dis(s1,t1) && dis(s2,u)+len+dis(v,t2)==di ...

  5. [BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA & 拓扑排序)

    Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间, ...

  6. BZOJ1880 [Sdoi2009]Elaxia的路线 【最短路 + dp】

    题目 最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提 ...

  7. 【BZOJ1880】[SDOI2009]Elaxia的路线 (最短路+拓扑排序)

    [SDOI2009]Elaxia的路线 题目描述 最近,\(Elaxia\)和\(w**\)的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间. \(El ...

  8. 【BZOJ1880】[Sdoi2009]Elaxia的路线(最短路)

    [BZOJ1880][Sdoi2009]Elaxia的路线(最短路) 题面 BZOJ 洛谷 题解 假装我们知道了任意两点间的最短路,那么我们怎么求解答案呢? 不难发现公共路径一定是一段连续的路径(如果 ...

  9. 【BZOJ1880】[Sdoi2009]Elaxia的路线 最短路+DP

    [BZOJ1880][Sdoi2009]Elaxia的路线 Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起 ...

随机推荐

  1. odoo 11 实现多个字段对应一个查询参数的查询

    在整理英语单词开发模块的过程中,有这样一个需求,就是我在查询界面里输入一个查询的值A,这个A可能是下面的任何一个值 1.一个英语单词  2.汉语文字  3.一个英语单词的部分 这里有两张表:engli ...

  2. NOIP2018题解

    Preface 联赛结束后趁着自己还没有一下子把题目忘光,所以趁机改一下题目. 没有和游记一起写主要是怕篇幅太长不美观. 因此这里我们直接讲题目,关于NOIP2018的一些心得和有趣的事详见:NOIP ...

  3. SequenceFile文件

    SequenceFile文件是Hadoop用来存储二进制形式的key-value对而设计的一种平面文件(Flat File).目前,也有不少人在该文件的基础之上提出了一些HDFS中小文件存储的解决方案 ...

  4. 校内模拟赛 旅行(by NiroBC)

    题意: n个点的无向图,Q次操作,每次操作可以连接增加一条边,询问两个点之间有多少条边是必经之路.如果不连通,输出-1. 分析: 首先并查集维护连通性,每次加入一条边后,如果这条边将会连接两个联通块, ...

  5. C_数据结构_递归自己调用自己

    # include <stdio.h> void f(int n) { ) printf("哈哈\n"); else f(n-i); } int main(void) ...

  6. 《Linux内核设计与实现》读书笔记三

    Chapter 18 调 试 18.1 准备开始 1.准备工作: 一个bug 一个藏匿bug的内核版本 相关内核代码的知识和运气 2.执行foo就会让程序立即产生核心信息转储(dump core). ...

  7. git学习笔记2——ProGit2

    先附上教程--<ProGit 2> 配置信息 Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量. 这些变量存储在三个不同的位置: /etc/git ...

  8. IP工具类

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletReques ...

  9. shell脚本--cut命令与awk简单使用

    cut:对内容进行列切割 -d 后面的是分割符,表示用什么符号来分割符来分割列,分隔符使用引号括起来: -f后面跟着要选择的字段列,从1开始,表示第一列,如果要多列,可以用逗号分隔 : -c参数后面跟 ...

  10. 使用node去爬虫

    let http = require('http'); let https = require('https');//引入node的https服务. let cheerio = require('ch ...