B3402 [Usaco2009 Open]Hide and Seek 捉迷藏 最短路

直接最短路板子,dij堆优化。

题干:

题目描述
    贝茜在和约翰玩一个“捉迷藏”的游戏.
    她正要找出所有适合她躲藏的安全牛棚.一共有N(2≤N≤20000)个牛棚,被编为1到N号.她知道约翰(捉牛者)从牛棚1出发.所有的牛棚由M(1≤M≤50000)条双向路连接,每条双向路连接两个不同的牛棚.所有的牛棚都是相通的.贝茜认为同牛棚1距离最远的的牛棚是安全的.两个牛棚间的距离是指,从一个牛棚到另一个牛棚最少需要通过的道路数量.请帮贝茜找出所有的安全牛棚.
输入格式
    第1行输入两个整数N和M,之后M行每行输入两个整数,表示一条路的两个端点.
   
输出格式
 仅一行,输出三个整数.第1个表示安全牛棚(如果有多个,输出编号最小的);第2个表示牛棚1和安全牛棚的距离;第3个表示有多少个安全的牛棚.

样例输入
6 7
3 6
4 3
3 2
1 3
1 2
2 4
5 2
样例输出
4 2 3
提示
没有写明提示

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
#define mp make_pair
#define pr pair<int,int>
const int INF = 1e9 + 7;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
int dis[20005];
struct node
{
    int l,r,nxt;
}a[100005];
int len = 0,lst[20005];
priority_queue <pr,vector <pr>,greater<pr> > q;
bool vis[20005];
void add(int x,int y)
{
    a[++len].l = x;
    a[len].r = y;
    a[len].nxt = lst[x];
    lst[x] = len;
}
void dij()
{
    memset(dis,60,sizeof(dis));
    clean(vis);
    dis[1] = 0;
    q.push(mp(dis[1],1));
    while(!q.empty())
    {
        pr u = q.top();
        q.pop();
        int x = u.second;
        if(vis[x])
        continue;
        vis[x] = 1;
        for(int i = lst[x];i;i = a[i].nxt)
        {
            int y = a[i].r;
            if(dis[y] > dis[x] + 1)
            {
                dis[y] = dis[x] + 1;
                q.push(mp(dis[y],y));
            }
        }
    }
}
int n,m;
int main()
{
    read(n);read(m);
    duke(i,1,m)
    {
        int x,y;
        read(x);read(y);
        add(x,y);
        add(y,x);
    }
    dij();
    int maxn = 0,cnt = 0,k = 0;
    duke(i,1,n)
    {
        if(maxn < dis[i])
        {
            maxn = dis[i];
            cnt = 1;
            k = i;
        }
        else if(maxn == dis[i])
        {
            cnt++;
        }
    }
//    cout<<endl;
    printf("%d %d %d\n",k,dis[k],cnt);
    return 0;
}

 

posted @ 2018-09-01 13:42  DukeLv  阅读(225)  评论(0编辑  收藏  举报