UVALive 6378 Friend Chains (多源最短路 spfa)

来源:互联网 发布:在线ps网站源码 编辑:程序博客网 时间:2024/05/19 07:10

题目链接:UVALive 6378
问题描述:
这里写图片描述

一开始读题没读懂,后来也理解错了……

多源最短路,floyd硬杠会超时(就算强行优化也会超时Orz)。spfa单源最短路算法循环一遍所有起点,邻接链表存边避免遍历大量无用点(直接用邻接矩阵存图,朴素spfa仍然会超时),鉴于题目中的用字符串描述对应关系,用map的特性优化。

有不少人是200+ms过的,可能是vector用时更短,vector不能存放边的权值,在这道题中使用没有什么问题。尝试改动代码后运行时间从850ms缩减到300+ms,其他的可能有初始化使用的memset比较费时等等,没有再尝试。

一道题让我学会了用邻接链表减少遍历次数+map容器(一个耿直的笑【我好渣啊】)。

手写邻接链表:

#include <iostream>#include <string>#include <cstdio>#include <algorithm>#include <cstring>#include <ctime>#include <queue>#include <map>#define MAX 20005#define M 1005#define INF 0x3f3f3f3fusing namespace std;map<string, int> name;int dist[M], head[M], cnt;bool vis[M];struct node{    int u, v, w, nxt;}edge[MAX];void add(int u, int v, int w){    edge[cnt].u = u;    edge[cnt].v = v;    edge[cnt].w = w;    edge[cnt].nxt = head[u];    head[u] = cnt++;    edge[cnt].u = v;    edge[cnt].v = u;    edge[cnt].w = w;    edge[cnt].nxt = head[v];    head[v] = cnt++;}void spfa(int s){    memset(dist, INF, sizeof(dist));    memset(vis, 0, sizeof(vis));    dist[s] = 0;    vis[s] = true;    queue<int> Q;    Q.push(s);    while(!Q.empty())    {        int u = Q.front();        Q.pop();        vis[u] = false;        for(int i = head[u]; i != -1; i = edge[i].nxt)        {            int v = edge[i].v;            if(dist[u] + edge[i].w < dist[v])            {                dist[v] = dist[u] + edge[i].w;                if(!vis[v])                {                    vis[v] = true;                    Q.push(v);                }            }        }    }}int main(){    int n, m;    string s, t1, t2;    while(scanf("%d", &n) && n)    {        cnt = 0;        name.clear();        memset(head, -1, sizeof(head));        for(int i = 0; i < n; i++)        {            cin >> s;            name[s] = i;//map查找优化        }        scanf("%d", &m);        while(m--)        {            cin >> t1 >> t2;            add(name[t1], name[t2], 1);        }        int Max = 0;        for(int i = 0; i < n; i++)        {            spfa(i);            for(int j = 0; j < n; j++)            {                Max = max(Max, dist[j]);                if(Max == INF)                    break;            }            if(Max == INF)                break;        }        if(Max != INF)            printf("%d\n", Max);        else            printf("-1\n");    }    return 0;}

hust Vjudge运行结果:
这里写图片描述

vector实现:

#include <iostream>#include <string>#include <cstdio>#include <algorithm>#include <cstring>#include <ctime>#include <queue>#include <map>#define M 2005#define INF 0x3f3f3f3fusing namespace std;map<string, int> name;int dist[M], cnt;bool vis[M];vector<int> edge[M];void spfa(int s){    memset(dist, INF, sizeof(dist));    memset(vis, 0, sizeof(vis));    dist[s] = 0;    vis[s] = true;    queue<int> Q;    Q.push(s);    while(!Q.empty())    {        int u = Q.front();        Q.pop();        vis[u] = false;        for(int i = 0; i < edge[u].size(); i++)        {            int v = edge[u][i];            if(dist[u] + 1 < dist[v])            {                dist[v] = dist[u] + 1;                if(!vis[v])                {                    vis[v] = true;                    Q.push(v);                }            }        }    }}int main(){    int n, m;    string s, t1, t2;    while(scanf("%d", &n) && n)    {        cnt = 0;        name.clear();        for(int i = 0; i < n; i++)//vector初始化            edge[i].clear();        for(int i = 0; i < n; i++)        {            cin >> s;            name[s] = i;//map查找优化        }        scanf("%d", &m);        while(m--)        {            cin >> t1 >> t2;            edge[name[t1]].push_back(name[t2]);            edge[name[t2]].push_back(name[t1]);        }        int Max = 0;        for(int i = 0; i < n; i++)        {            spfa(i);            for(int j = 0; j < n; j++)            {                Max = max(Max, dist[j]);                if(Max == INF)                    break;            }            if(Max == INF)                break;        }        if(Max != INF)            printf("%d\n", Max);        else            printf("-1\n");    }    return 0;}

hust Vjudge运行结果:
这里写图片描述

0 0
原创粉丝点击