BZOJ-1880 Elaxia的路線 SPFA+枚舉

1880: [Sdoi2009]Elaxia的路線
Time Limit: 4 Sec Memory Limit: 64 MB
Submit: 921 Solved: 354
[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
Day2

竟然自己rush出了正解,開心

題解:
4遍spfa,開四個dis數組,分別記錄st1,st2,ed1,ed2到各點的最短路,然後枚舉點對(i,j)判斷i,j是否在最短路徑上,然後更新答案即可.

PS:網上的好像都是DP啊,拓撲啊什麼的.....

code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
int read()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
#define maxn 1510
#define maxm 500010
int n,m,ans;
int st1,st2,ed1,ed2;
int len1,len2;
struct data{int to,next,tim;}edge[maxm*2];
int head[maxn],cnt;

void add(int u,int v,int t)
{
    cnt++;
    edge[cnt].next=head[u]; head[u]=cnt;
    edge[cnt].to=v; edge[cnt].tim=t;
}
void insert(int u,int v,int t)
{
    add(u,v,t); add(v,u,t);
}

int disst1[maxn],disst2[maxn],dised1[maxn],dised2[maxn];
bool visit[maxn];
#define inf 0x7fffffff
void spfa(int s,int* dis)
{
    queue<int>q;
    for (int i=1; i<=n; i++) dis[i]=inf;
    q.push(s); dis[s]=0;
    while (!q.empty())
        {
            int now=q.front(); q.pop();
            for (int i=head[now]; i; i=edge[i].next)
                if (dis[now]+edge[i].tim<dis[edge[i].to])
                    {
                        dis[edge[i].to]=edge[i].tim+dis[now];
                        if (!visit[edge[i].to])
                            {
                                q.push(edge[i].to);
                                visit[edge[i].to]=1;
                            }
                    }
            visit[now]=0;
        }
}

bool check(int loc)
{
    if (disst1[loc]+dised1[loc]!=len1 || disst2[loc]+dised2[loc]!=len2) 
        return false;
    return true;
}

int main()
{
    n=read(),m=read();
    st1=read(),ed1=read(),st2=read(),ed2=read();
    for (int i=1; i<=m; i++)
        {
            int u=read(),v=read(),t=read();
            insert(u,v,t);
        }
    spfa(st1,disst1); spfa(st2,disst2);
    spfa(ed1,dised1); spfa(ed2,dised2);
    len1=disst1[ed1]; len2=disst2[ed2];
    for (int i=1; i<=n; i++)
        if (check(i))
            for (int j=1; j<=n; j++)
                if (check(j))
                    ans=max(ans,abs(disst1[i]-disst1[j]));
    printf("%d\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章