• 【BZOJ 1880】 [Sdoi2009]Elaxia的路线 (最短路树)


    1880: [Sdoi2009]Elaxia的路线

    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

    【分析】

      题意就是求最短路的最长交。

      我们先做两次最短路求出最短路树(其实是拓扑图),然后交边给值,然后我再跑一遍最长路就好了。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 2010
      9 #define Maxm 500010
     10 #define INF 0xfffffff
     11 
     12 int n;
     13 
     14 struct node
     15 {
     16     int x,y,c,next;
     17 }t[Maxm*2],tt[Maxm*3];
     18 int first[Maxn],len;
     19 
     20 void ins(int x,int y,int c)
     21 {
     22     t[++len].x=x;t[len].y=y;t[len].c=c;
     23     t[len].next=first[x];first[x]=len;
     24 }
     25 
     26 int x1,y1,x2,y2;
     27 int st,ed;
     28 
     29 queue<int > q;
     30 
     31 int dis[3][Maxn];
     32 bool inq[Maxn];
     33 void spfa(int k)
     34 {
     35     while(!q.empty()) q.pop();
     36     memset(dis[k],63,sizeof(dis[k]));
     37     memset(inq,0,sizeof(inq));
     38     inq[st]=1;q.push(st);dis[k][st]=0;
     39     while(!q.empty())
     40     {
     41         int x=q.front();
     42         for(int i=first[x];i;i=t[i].next)
     43         {
     44             int y=t[i].y;
     45             if(dis[k][y]>dis[k][x]+t[i].c)
     46             {
     47                 dis[k][y]=dis[k][x]+t[i].c;
     48                 if(!inq[y])
     49                 {
     50                     q.push(y);
     51                     inq[y]=0;
     52                 }
     53             }
     54         }
     55         q.pop();inq[x]=0;
     56     }
     57 }
     58 
     59 void spfa2(int k)
     60 {
     61     while(!q.empty()) q.pop();
     62     // memset(dis[k],63,sizeof(dis[k]));
     63     for(int i=1;i<=n;i++) dis[k][i]=-INF;
     64     memset(inq,0,sizeof(inq));
     65     inq[st]=1;q.push(st);dis[k][st]=0;
     66     while(!q.empty())
     67     {
     68         int x=q.front();
     69         for(int i=first[x];i;i=t[i].next)
     70         {
     71             int y=t[i].y;
     72             if(dis[k][y]<dis[k][x]+t[i].c)
     73             {
     74                 dis[k][y]=dis[k][x]+t[i].c;
     75                 if(!inq[y])
     76                 {
     77                     q.push(y);
     78                     inq[y]=0;
     79                 }
     80             }
     81         }
     82         q.pop();inq[x]=0;
     83     }
     84 }
     85 
     86 bool pd(int x)
     87 {
     88     if(dis[2][tt[x].y]+dis[1][tt[x].y]!=dis[1][y2]||dis[2][tt[x].x]+dis[1][tt[x].x]!=dis[1][y2]) return 0;
     89     if(dis[1][tt[x].x]==dis[1][tt[x].y]+tt[x].c) return 1;
     90     if(dis[1][tt[x].y]==dis[1][tt[x].x]+tt[x].c) return 1;
     91     return 0;
     92 }
     93 
     94 int main()
     95 {
     96     int m;
     97     scanf("%d%d",&n,&m);
     98     scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
     99     len=0;
    100     for(int i=1;i<=m;i++)
    101     {
    102         int x,y,c;
    103         scanf("%d%d%d",&x,&y,&c);
    104         ins(x,y,c);ins(y,x,c);
    105     }
    106     int ans1,ans2;
    107     st=x1;spfa(0);
    108     st=x2;spfa(1);
    109     // st=y1;spfa(2);
    110     st=y2;spfa(2);
    111     // for(int i=1;i<=n;i++) printf("%d ",dis[0][i]);printf("
    ");
    112     // for(int i=1;i<=n;i++) printf("%d ",dis[1][i]);printf("
    ");
    113     st=n+1,ed=st+1;
    114     memset(first,0,sizeof(first));
    115     int ln=len;len=0;
    116     // tt=t;
    117     for(int i=1;i<=ln;i++) tt[i]=t[i];
    118     for(int i=1;i<=ln;i++)
    119     {
    120         if(pd(i)&&dis[0][tt[i].y]==dis[0][tt[i].x]+tt[i].c)
    121         {
    122             ins(tt[i].x,tt[i].y,tt[i].c);
    123         }
    124         else if(dis[0][tt[i].y]==dis[0][tt[i].x]+tt[i].c)
    125         {
    126             ins(tt[i].x,tt[i].y,0);
    127         }
    128     }
    129     // for(int i=1;i<=len;i++) printf("%d %d %d
    ",t[i].x,t[i].y,t[i].c);
    130     // return 0;
    131     // ins(st,x1,0);ins(st,x2,0);
    132     // ins(y1,ed,0);ins(y2,ed,0);
    133     st=x1;ed=y1;
    134     spfa2(0);
    135     int ans=dis[0][ed];
    136     printf("%d
    ",ans);
    137     return 0;
    138 }
    View Code

    2017-03-05 16:01:53

  • 相关阅读:
    Android 自定义View (一)
    Java enum的用法详解
    Android Application的使用及其生命周期
    android 支持的语言列表(汇总)
    android 使用String.format("%.2f",67.876)自已定义语言(俄语、西班牙语)会把小数点变为逗号
    TN2151:崩溃报告
    android 各国语言对应的缩写
    uva 1401 dp+Trie
    教你3网页特效免费下载栅极材料必不可少的一步,无需工具
    编译命令行终端 swift
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6505685.html
Copyright © 2020-2023  润新知