2012 Asia Hangzhou Regional Contest--hdu4460Friend Chains(SPFA)

来源:互联网 发布:cab a4 编辑软件 编辑:程序博客网 时间:2024/04/30 16:55

题目请戳这里

题目大意:给n个人,m个关系,组成了一张关系网,求一个k使任意2个人在关系网中距离不大于k。

题目分析:

12年杭州现场赛四大水题之一。

就是在无向图中求出任意2点距离最小值,取最小值的最大值为k。任意2点最小值很容易想到floyd,不过此题的点数达到1000,O(n^3)压力山大。所以可以做n个spfa。枚举起点跑n次spfa,一次spfa时间复杂度大约O(ke),所以总的时间复杂度就是O(nke),k一般比较小,可以承受。

不过跑的不是很快。。。

详情请见代码:

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<cstdlib>#include<cctype>#include<map>#include<vector>#include<set>#include<queue>#include<string>using namespace std;const int inf = 0x3f3f3f3f;const double eps = 1e-6;const double PI = acos(-1.0);typedef __int64 ll;const int N = 1001;const int M = 10005;map<string,int>lcm;int ans;int n,m,num;struct node{    int to,next,dis;}g[M + M];int head[N],que[N];string a,b;int dist[N];bool flag[N];void build(int s,int e,int v){    g[num].to = e;    g[num].dis = v;    g[num].next = head[s];    head[s] = num ++;}void spfa(int st){    memset(flag,false,sizeof(flag));    int i,front,rear;    memset(dist,0x3f,sizeof(dist));    front = rear = 0;    flag[st] = true;    dist[st] = 0;    que[rear ++] = st;    while(front != rear)    {        int u = que[front ++];        flag[u] = false;        if(front == N)            front = 0;        for(i = head[u];~i;i = g[i].next)        {            int v = g[i].to;            if(dist[v] > dist[u] + g[i].dis)            {                dist[v] = dist[u] + g[i].dis;                if(flag[v] == false)                {                    flag[v] = true;                    que[rear ++] = v;                    if(rear == N)                        rear = 0;                }            }        }    }    for(i = 1;i <= n;i ++)    {        if(i == st)            continue;        ans = max(ans,dist[i]);    }}void gao(){    for(int i = 1;i <= n;i ++)        spfa(i);}int main(){    int i;    while(scanf("%d",&n),n)    {        memset(head,-1,sizeof(head));        num = 1;        lcm.clear();        for(i = 1;i <= n;i ++)        {            cin>>a;            lcm[a] = i;        }        scanf("%d",&m);        while(m --)        {            cin>>a>>b;            build(lcm[a],lcm[b],1);            build(lcm[b],lcm[a],1);        }        ans = 0;        gao();        if(ans == inf)            ans = -1;        printf("%d\n",ans);    }    return 0;}


原创粉丝点击