BZOJ1880 SDOI2009 Elaxia的路线 最短路+拓扑排序

题意:给定两个点对和一张无向图,求两个点对的最短路中,重边边权和的最大值

题解:

首先从给出的四个点出发跑出到其他所有点的最短路,然后判断哪些边是重边。找出所有重边后,将其构有向图,在该图上用拓扑排序求最长路。

开始的时候枚举每一条边我没有建反向边,而是每次判定的时候互换一下边的始末点看是否合法,结果最后一个点死活过不去。后来上网搜题解才知道,必须建反向边,与原边分别判断。果然偷懒就是不行啊……

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <deque>
using namespace std;
#define INF 6666666

const int MAXN=1500+2;
const int MAXM=300000+2;
struct Hash{
    int u,w;
    Hash *Next;
    Hash(){}
    Hash(int _u,int _w,Hash *_Next):u(_u),w(_w),Next(_Next){}
}*Tab[2][MAXN],mem[6*MAXM];
int N,M,cnt[2],d[4][MAXN],c[MAXN],X1,Y1,X2,Y2,Ans;
bool Flag[MAXN];
deque<int> q;

void Insert(int t,int u,int v,int w){ Tab[t][u]=&(mem[cnt[t]++]=Hash(v,w,Tab[t][u]));}

void SPFA(int s,int *d){
    for(int i=1;i<=N;i++) d[i]=INF;
    d[s]=0,q.push_front(s);

    int x;
    while(!q.empty()){
        x=q.front(),q.pop_front();
        for(Hash *p=Tab[0][x];p;p=p->Next){
            if(d[p->u]<=d[x]+p->w) continue;
            d[p->u]=d[x]+p->w;
            if(Flag[p->u]) continue;
            Flag[p->u]=1;

            if(!q.empty() && d[p->u]<=d[q.front()]) q.push_front(p->u);
            else q.push_back(p->u);
        }
        Flag[x]=0;
    }
}

bool Check1(int u,int v,int w){
    if(d[0][u]+d[1][v]+w!=d[0][Y1]) return 0;
    if(d[2][u]+d[3][v]+w!=d[2][Y2]) return 0;
    return 1;
}

bool Check2(int u,int v,int w){
    if(d[0][u]+d[1][v]+w!=d[0][Y1]) return 0;
    if(d[2][u]+d[3][v]+w!=d[2][X2]) return 0;
    return 1;
}

int Topologic_Sort(){
    memset(d[2],0,sizeof(d[0]));
    for(int i=1;i<=N;i++)
        if(!c[i]) q.push_back(i);

    int x;
    while(!q.empty()){
        x=q.front(),q.pop_front();
        for(Hash *p=Tab[1][x];p;p=p->Next){
            c[p->u]--,d[2][p->u]=max(d[2][p->u],d[2][x]+p->w);
            if(!c[p->u]) q.push_back(p->u);
        }
    }

    int Ans=-1;
    for(int i=1;i<=N;i++) Ans=max(Ans,d[2][i]);
    return Ans;
}

int main(){
    cin >> N >> M >> X1 >> Y1 >> X2 >> Y2;
    for(int i=1,u,v,w;i<=M;i++){
        scanf("%d %d %d",&u,&v,&w);
        Insert(0,u,v,w),Insert(0,v,u,w);
    }

    SPFA(X1,d[0]),SPFA(Y1,d[1]),SPFA(X2,d[2]),SPFA(Y2,d[3]);
    for(int i=1;i<=N;i++)
        for(Hash *p=Tab[0][i];p;p=p->Next)
            if(Check1(i,p->u,p->w)) Insert(1,i,p->u,p->w),c[p->u]++;
    Ans=Topologic_Sort();

    SPFA(Y2,d[2]),SPFA(X2,d[3]);
    memset(Tab[1],0,sizeof(Tab[1]));
    for(int i=1;i<=N;i++)
        for(Hash *p=Tab[0][i];p;p=p->Next)
            if(Check2(i,p->u,p->w)) Insert(1,i,p->u,p->w),c[p->u]++;
    cout << max(Ans,Topologic_Sort()) << endl;

    return 0;
}

时间: 2024-08-28 21:41:24

BZOJ1880 SDOI2009 Elaxia的路线 最短路+拓扑排序的相关文章

bzoj 1880: [Sdoi2009]Elaxia的路线【spfa+拓扑排序】

有趣啊 先spfa分别求出以s1,t1,s2,t2为起点的最短路,然后把在s1-->t1或者s2-->t2最短路上的边重新建有向图,跑拓扑最长路即可 #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> using namespace std; const int N=1505,inf=1e9; int n,m,x1

bzoj1880: [Sdoi2009]Elaxia的路线

1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1035  Solved: 412[Submit][Status][Discuss] Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长. 现在已知的是E

BZOJ 1880: [Sdoi2009]Elaxia的路线( 最短路 + dp )

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

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

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

luogu P2149 [SDOI2009]Elaxia的路线 |最短路+建最短路图+卡常数

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

bzoj 1880: [Sdoi2009]Elaxia的路线(拓扑排序+spfa)

1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 974  Solved: 382 [Submit][Status][Discuss] Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长. 现在已知的是

【BZOJ 1880】 [Sdoi2009]Elaxia的路线

1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 660  Solved: 242 [Submit][Status][Discuss] Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长. 现在已知的是

[SDOI2009]Elaxia的路线

P2149 [SDOI2009]Elaxia的路线 求无向图中,两对点间最短路的最长公共路径 喵啊-这题真心喵啊-orzorz 先spfa求出x1, y1, x2, y2的单源最短路 然后把x1到y1的最短路们建图 判断方式(精髓!): if(dis[0][uu] + ww + dis[1][vv] == dis[0][y1]){ addedge(uu, vv, ww, 1); ind[vv]++; } 蒟蒻欲膜又止[划掉 注意 建完是有向图哦 在建完图之后 用同样的方式判断这个新图上有哪些边在

[SDOI2009]Elaxia的路线 SPFA+Topo

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