[BFS]JZOJ 4671 World Tour

Description

Cicasso是一个著名的雕塑家。
现在他想去城市之间旅游,他是一个聪明的人,所以从一个城市到另一个城市他只会走最短路。他想游览全国的风景,所以他想走的路的总长度尽量长,但是经费有限,他只能去四个城市,而且这四个城市不能重复(在途中经过的城市不计算,例如 ,他要去的四个城市有上标,[1, 5, 2, 4],这样是合法的)
注意,道路是单向路,并且距离都为1。
 

Input

在第一行有两个整数n和m(4<=n<=3000,3<=m<=5000),n代表城市数,m代表单向边的数量
接下来m行有两个整数ui,vi(ui,vi<=n)——代表一条从ui到vi的单向边,注意ui和vi可能相同,并且同两个城市之间可能有多条边

Output

输出四个整数,代表Cicasso要旅游的路线。
 

Sample Input

8 9
1 2
2 3
3 4
4 1
4 5
5 6
6 7
7 8
8 5

Sample Output

2 1 8 7
 
d(2,1)=3,d(1,8)=7,d(8,7)=3,总共的距离等于13
 

Data Constraint

对于10% n<=10
对于20% n<=100
对于 30% n<=1000
对于100% n<=3000

分析

我还以为是什么奇怪的东西呢,点就四个

我们只需要预处理出距离每个点最远和次远的点的距离和点,然后枚举四个点中间的两个点,先选择它们的最远点,若最远点重合,则选次远点

 

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <queue>
using namespace std;
const int N=3e3+10;
const int Inf=0x3f3f3f3f;
struct Edge {
    int u,v,nx;
}g[2*N];
int cnt,list[N],d[N][N],mx[N][2],revmx[N][2];
int n,m;

void Add(int u,int v) {
    g[++cnt]=(Edge){u,v,list[u]};list[u]=cnt;
}

void BFS() {
    queue<int> from,to;
    while (!from.empty()) from.pop();
    while (!to.empty()) to.pop();
    for (int i=1;i<=n;i++) d[i][i]=0,from.push(i),to.push(i);
    while (!from.empty()) {
        int f=from.front(),u=to.front();from.pop();to.pop();
        for (int i=list[u];i;i=g[i].nx)
            if (d[f][g[i].v]>d[f][u]+1) {
                d[f][g[i].v]=d[f][u]+1;
                from.push(f);to.push(g[i].v);
            }
    }
}

void Pre_Process() {
    for (int i=1;i<=n;i++) {
        mx[i][0]=mx[i][1]=revmx[i][0]=revmx[i][1]=i;
        for (int j=1;j<=n;j++)
            if (i!=j) {
                if (d[i][j]!=Inf)
                if (d[i][j]>d[i][mx[i][0]]) mx[i][1]=mx[i][0],mx[i][0]=j;
                else if (d[i][j]>mx[i][1]) mx[i][1]=j;
                if (d[j][i]!=Inf)
                if (d[j][i]>d[revmx[i][0]][i]) revmx[i][1]=revmx[i][0],revmx[i][0]=j;
                else if (d[j][i]>d[revmx[i][1]][i]) revmx[i][1]=j;
            }
    }
}

int main() {
    scanf("%d%d",&n,&m);
    for (int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),Add(u,v);
    memset(d,0x3f,sizeof d);BFS();
    Pre_Process();
    int ans=0,a1,a2,a3,a4;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            if (i!=j&&d[i][j]!=Inf)
                for (int k=0;k<2;k++)
                    for (int l=0;l<2;l++) {
                        int u1=revmx[i][k],v1=mx[j][l];
                        if (u1==v1||u1==i||u1==j||v1==i||v1==j) continue;
                        if (d[u1][i]+d[i][j]+d[j][v1]>ans)
                            ans=d[u1][i]+d[i][j]+d[j][v1],a1=u1,a2=i,a3=j,a4=v1;
                    }
    printf("%d %d %d %d\n",a1,a2,a3,a4);
}
View Code

 

posted @ 2019-04-25 19:51  Vagari  阅读(127)  评论(0编辑  收藏  举报