zoukankan      html  css  js  c++  java
  • BZOJ 1880: [Sdoi2009]Elaxia的路线( 最短路 + dp )

    找出同时在他们最短路上的边(dijkstra + dfs), 组成新图, 新图DAG的最长路就是答案...因为两人走同一条路但是不同方向也可以, 所以要把一种一个的s,t换一下再更新一次答案 

    --------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
     
    using namespace std;
     
    const int maxn = 1509;
    const int inf = 0x3f3f3f3f;
     
    struct edge {
    int to, w, f;
    edge* next;
    } E[2000000], *pt = E, *head[maxn];
     
    void AddEdge(int u, int v, int w) {
    pt->to = v; pt->w = w; pt->f = 0; pt->next = head[u]; head[u] = pt++;
    }
     
    int N, s0, t0, s1, t1, ans = 0;
    int d[maxn], w[maxn], deg[maxn];
    bool vis[maxn];
     
    void init() {
    int m;
    scanf("%d%d%d%d%d%d", &N, &m, &s0, &t0, &s1, &t1);
    s0--; t0--; s1--; t1--;
    while(m--) {
    int u, v, w; scanf("%d%d%d", &u, &v, &w); u--; v--;
    AddEdge(u, v, w);
    AddEdge(v, u, w);
    }
    }
     
    struct node {
    int x, d;
    bool operator < (const node &o) const {
    return d > o.d;
    }
    };
     
    priority_queue<node> q;
     
    void Dijkstra(int s) {
    memset(d, inf, sizeof d); d[s] = 0;
    q.push((node){s, 0});
    while(!q.empty()) {
    node o = q.top(); q.pop();
    if(d[o.x] != o.d) continue;
    int x = o.x;
    for(edge* e = head[x]; e; e = e->next) if(d[e->to] > d[x] + e-> w) {
    d[e->to] = d[x] + e->w;
    q.push((node){e->to, d[e->to]});
    }
    }
    }
     
    void dfs(int x) {
    if(vis[x]) return;
    vis[x] = true;
    for(edge* e = head[x]; e; e = e->next)
    if(d[e->to] + e->w == d[x]) dfs(e->to);
    }
     
    void DFS(int x) {
    vis[x] = true;
    w[x] = 0;
    for(edge* e = head[x]; e; e = e->next) if(e->f == 2 && !vis[e->to]) {
    DFS(e->to);
    w[x] = max(w[x], w[e->to] + e->w);
    }
    }
     
    int main() {
    init();
    memset(vis, 0, sizeof vis);
    Dijkstra(s0); dfs(t0);
    for(int i = 0; i < N; i++) if(vis[i])
    for(edge* e = head[i]; e; e = e->next)
    if(d[e->to] == d[i] + e->w && vis[e->to]) e->f++;
    memset(vis, 0, sizeof vis);
    Dijkstra(s1); dfs(t1);
    for(int i = 0; i < N; i++) if(vis[i])
    for(edge* e = head[i]; e; e = e->next)
    if(d[e->to] == d[i] + e->w && vis[e->to]) e->f++;
    memset(vis, 0, sizeof vis);
    memset(deg, 0, sizeof deg);
    memset(w, 0, sizeof w);
    for(int i = 0; i < N; i++)
    for(edge* e = head[i]; e; e = e->next)
    if(e->f == 2) deg[e->to]++;
    for(int i = 0; i < N; i++) if(!deg[i]) DFS(i);
    for(int i = 0; i < N; i++) ans = max(ans, w[i]);
    memset(vis, 0, sizeof vis);
    Dijkstra(t1); dfs(s1);
    for(int i = 0; i < N; i++) if(vis[i])
    for(edge* e = head[i]; e; e = e->next)
    if(d[e->to] == d[i] + e->w && vis[e->to]) e->f++;
    memset(vis, 0, sizeof vis);
    memset(deg, 0, sizeof deg);
    memset(w, 0, sizeof w);
    for(int i = 0; i < N; i++)
    for(edge* e = head[i]; e; e = e->next)
    if(e->f == 2) deg[e->to]++;
    for(int i = 0; i < N; i++) if(!deg[i]) DFS(i);
    for(int i = 0; i < N; i++) ans = max(ans, w[i]);
    printf("%d ", ans);
    return 0;
    }

    -------------------------------------------------------------------------------- 

    1880: [Sdoi2009]Elaxia的路线

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 884  Solved: 332
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    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

    Sample Output

    3

    HINT

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

    Source

  • 相关阅读:
    查看linux版本的三种常用方法
    CentOS和Redhat发行版linux内核版本的对应关系
    swift的异常处理:本质是错误信息的传递方式
    构建法则第一条:有什么材料做什么饭
    待解决问题 代码阅读
    iOS: 聊聊 Designated Initializer(指定初始化函数):NS_DESIGNATED_INITIALIZER
    整合与构建的能力是创造性思维的重要体现
    iOS网络缓存的系统实现是一个烂尾工程
    (动态)代理于HOOK的区别于关系
    iOS 网络缓存总结
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4934696.html
Copyright © 2011-2022 走看看