zoukankan      html  css  js  c++  java
  • [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
    ",a1,a2,a3,a4);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    Java知识点:javac命令
    Java知识点:内部类
    证明:寝室分配问题是NPC问题
    Java知识点:Object类
    Java 知识点:序列化
    Python3玩转儿 机器学习(2)
    Python3玩转儿 机器学习(1)
    python re模块findall使用
    百度URL 部分参数
    python datetime模块
  • 原文地址:https://www.cnblogs.com/mastervan/p/10770547.html
Copyright © 2011-2022 走看看