HDU 4460 SPFA

HDU 4460
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4460
题意:
一些点(<=1e3)一些边(<=1e5)。问任意两点最大距离多少。若不联通输出-1.
思路:
原来spfa一直搞错了,用优先队列的叫dij,不用的叫spfa……有时候加优先队列还会慢,因为有个O(logn)的复杂度在那里,而且一个点因为不同的距离值会入队多次,所以不能最短路总是上优先队列。
复现的时候算了下复杂度,总觉得O(M)才是比较靠谱的,感觉这样单纯暴力枚举是过不了的,于是往连通性方面搞了下,两个小时后就弃题了……
实际上,可能是数据水,纯spfa也是能过的……也是脑卡,都成全场题了为什么不试一发……spfa的复杂度用BELLMAN-FORD的复杂度去考虑,最差O(n^2),最好O(n)。
源码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <map>
using namespace std;
const int MAXN = 1000 + 5;
#define inf (1000000007)
int d[MAXN];
struct D
{
    int u, d;
    bool operator < (const D&rbs)const{
        return d < rbs.d;
    }
};
vector<int>lin[MAXN];
queue<int>que;
char s1[MAXN], s2[MAXN];
map<string, int>mm;
int ans;
int vis[MAXN];
int n, m;
void bfs(int u)
{
//    printf("org u = %d\n", u);
    for(int i = 1 ; i <= n ; i++)
        d[i] = inf, vis[i] = 0;
    while(!que.empty()) que.pop();
    vis[u] = 1, d[u] = 0, que.push(u);
    while(!que.empty()){
        u = que.front();  que.pop();
//        printf("u = %d\n", u);
        vis[u] = 0;
        for(int j = 0 ; j < (int)lin[u].size() ; j++){
            int v = lin[u][j];
            if(d[v] > d[u] + 1){
//                printf("v = %d\n", v);
                d[v] = d[u] + 1;
                if(vis[v] == 0) que.push(v), vis[v] = 1;
            }
        }
    }
//    for(int i = 1 ; i <= n ; i++)   printf("d[%d] = %d\n", i, d[i]);
    for(int i = 1 ; i <= n ; i++)
        ans = max(ans, d[i]);
}
int main()
{
//    freopen("HDU 4460.in", "r", stdin);
    while(scanf("%d", &n) != EOF && n){
        mm.clear();
        for(int i = 1 ; i <= n ; i++){
            scanf("%s", s1);
            mm[s1] = i;
            lin[i].clear();
        }
        scanf("%d", &m);
        for(int i = 1 ; i <= m ; i++){
            scanf("%s%s", s1, s2);
//            printf("first = %d, second = %d\n", mm[s1], mm[s2]);
            lin[mm[s1]].push_back(mm[s2]);
            lin[mm[s2]].push_back(mm[s1]);
        }
        ans = 0;
        for(int i = 1 ; i <= n ; i++)
            bfs(i);
        if(ans == inf)   printf("-1\n");
        else    printf("%d\n", ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值