题目链接

题目描述

奶牛贝西和农夫约翰(FJ)玩捉迷藏,现在有N个谷仓,FJ开始在第一个谷仓,贝西为了不让FJ找到她,当然要藏在距离第一个谷仓最远的那个谷仓了。现在告诉你N个谷仓,和M个两两谷仓间的“无向边”。每两个仓谷间当然会有最短路径,现在要求距离第一个谷仓(FJ那里)最远的谷仓是哪个(所谓最远就是距离第一个谷仓最大的最短路径)?如有多个则输出编号最小的。以及求这最远距离是多少,和有几个这样的谷仓距离第一个谷仓那么远。

输入格式

* Line 1: Two space-separated integers: N and M

* Lines 2..M+1: Line i+1 contains the endpoints for path i: A_i and B_i

第一行:两个整数N,M;

第2-M+1行:每行两个整数,表示端点A_i 和 B_i 间有一条无向边。

输出格式

* Line 1: On a single line, print three space-separated integers: the index of the barn farthest from barn 1 (if there are multiple such barns, print the smallest such index), the smallest number of paths needed to reach this barn from barn 1, and the number of barns with this number of paths.

仅一行,三个整数,两两中间空格隔开。表示:距离第一个谷仓最远的谷仓编号(如有多个则输出编号最小的。),以及最远的距离,和有几个谷仓距离第一个谷仓那么远。

 

题解

我们先求出1到每个点的最短路,然后从中取最大值即可,跑一遍dijkstra即可。

ps:这在luogu交一遍都到了最优解第2面,看来堆优化dijkstra还是非常重要

#include<bits/stdc++.h>
using namespace std;
int d[270000],v[270000];
int pre[270000],son[270000],dis[270000],now[270000],tot;
int n,m,maxx,ans;
void read(int &x)
{
    char c=getchar();int f=0;x=0;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    if(f==-1)x=-x;
}
void add(int x,int y,int z)
{
    pre[++tot]=now[x];
    son[tot]=y;
    now[x]=tot;
    dis[tot]=z;
}
void dij()
{
    memset(d,63,sizeof(d));
    memset(v,0,sizeof(v));
    priority_queue<pair<int,int> >q;
    d[1]=0;q.push(make_pair(0,1));
    while(!q.empty())
    {
        int x=q.top().second;q.pop();
        if(v[x])continue;
        v[x]=1;
        for(int i=now[x];i;i=pre[i])
        {
            int y=son[i];
            if(d[y]>d[x]+dis[i])
            {
                d[y]=d[x]+dis[i];
                q.push(make_pair(-d[y],y));
            }
        }
    }
}
int main()
{
    read(n);read(m);
    for(int i=1,x,y,z;i<=m;i++)
    {
        read(x);read(y);z=1;
        add(x,y,z);add(y,x,z);
    }
    dij();
    for(int i=1;i<=n;i++)
    maxx=max(maxx,d[i]);
    for(int i=1;i<=n;i++)
    {
        if(d[i]==maxx)
        {
            ans++;
            if(ans==1)printf("%d ",i);
        }
    }
    printf("%d %d",maxx,ans);
    return 0;
}