当前位置:编程学习 > C/C++ >>

UVa 10986 - Sending email (Dijkstra优化, SPFA)

题目:
Problem E
Sending email
Time Limit: 3 seconds
"A new internet watchdog is creating a stir in
Springfield. Mr. X, if that is his real name, has
come up with a sensational scoop."Kent Brockman
There are n SMTP servers connected by network cables. Each of the m cables connects two computers and has a certain latency measured in milliseconds required to send an email message. What is the shortest time required to send a message from server S to server T along a sequence of cables? Assume that there is no delay incurred at any of the servers.
Input
The first line of input gives the number of cases, N. N test cases follow. Each one starts with a line containing n(2<=n<20000), m (0<=m<50000), S (0<=S<n) and T (0<=T<n). S!=T. The next m lines will each contain 3 integers: 2 different servers (in the range [0, n-1]) that are connected by a bidirectional cable and the latency, w, along this cable (0<=w<=10000).
Output
For each test case, output the line "Case #x:" followed by the number of milliseconds required to send a message from S toT. Print "unreachable" if there is no route from S to T.
Sample Input Sample Output
3
2 1 0 1
0 1 100
3 3 2 0
0 1 100
0 2 200
1 2 50
2 0 0 1
Case #1: 100
Case #2: 150
Case #3: unreachable
Problemsetter: Igor Naverniouk

题目大意:
给一个图, 求从s点到t点的最小距离。

分析与总结:
易做图裸的最短路,但n太大显然是不能用邻接矩阵的,需要用邻接表+优先队列优化。


代码:
1. Dijkstra,  0.148s
[cpp] 
#include<cstdio> 
#include<cstring> 
#include<utility> 
#include<queue> 
using namespace std; 
 
typedef pair<int,int>pii; 
 
priority_queue<pii,vector<pii>,greater<pii> >q; 
 
const int N = 100005; 
const int INF = 1000000000; 
 
int n, m, beg, end, k; 
int head[N], next[N], u[N], v[N], w[N], d[N]; 
bool vis[N]; 
  
inline void read_graph(){ 
    scanf("%d%d%d%d",&n,&m,&beg,&end); 
    memset(head, -1, sizeof(head)); 
    for(int e=1; e<=m; ++e){ 
        scanf("%d%d%d",&u[e],&v[e],&w[e]); 
        u[e+m]=v[e], v[e+m]=u[e], w[e+m]=w[e]; 
        next[e] = head[u[e]]; 
        head[u[e]] = e; 
        next[e+m] = head[u[e+m]]; 
        head[u[e+m]] = e+m; 
    } 

 
inline void Dijkstra(int src){ 
    memset(vis, 0, sizeof(vis)); 
    for(int i=0; i<n; ++i) d[i] = INF; 
    d[src] = 0; 
    q.push(make_pair(d[src], src)); 
    while(!q.empty()){ 
        pii u = q.top();  q.pop(); 
        int x = u.second; 
        if(vis[x]) continue; 
        vis[x] = true; 
        for(int e=head[x]; e!=-1; e=next[e])if(d[v[e]] > d[x]+w[e]){ 
            d[v[e]] = d[x]+w[e]; 
            q.push(make_pair(d[v[e]], v[e])); 
        } 
    } 

 
int main(){ 
    int T,cas=1; 
    scanf("%d",&T); 
    while(T--){ 
        read_graph(); 
        Dijkstra(beg); 
        printf("Case #%d: ",cas++); 
        if(d[end]!=INF) printf("%d\n", d[end]); 
        else puts("unreachable"); 
    } 
    return 0; 


2.SPFA,  0.160s
[cpp] 
#include<cstdio> 
#include<cstring> 
#include<utility> 
#include<queue> 
using namespace std; 
 
queue<int>q; 
 
const int N = 100005; 
const int INF = 1000000000; 
 
int n, m, beg, end, k; 
int head[N], next[N], u[N], v[N], w[N], d[N]; 
bool vis[N]; 
  
inline void read_graph(){ 
    scanf("%d%d%d%d",&n,&m,&beg,&end); 
    memset(head, -1, sizeof(head)); 
    for(int e=1; e<=m; ++e){ 
        scanf("%d%d%d",&u[e],&v[e],&w[e]); 
        u[e+m]=v[e], v[e+m]=u[e], w[e+m]=w[e]; 
        next[e] = head[u[e]]; 
        head[u[e]] = e; 
        next[e+m] = head[u[e+m]]; 
        head[u[e+m]] = e+m; 
    } 

 
inline void SPFA(int src){ 
    memset(vis, 0, sizeof(vis)); 
    for(int i=0; i<n; ++i) d[i] = INF; 
    d[src] = 0; 
 
    q.push(src); 
    while(!q.empty()){ 
        int u = q.front();  q.pop(); 
        vis[u] = false; 
        for(int e=head[u]; e!=-1; e=next[e])if(d[v[e]] > d[u]+w[e]){ 
            d[v[e]] = d[u] + w[e]; 
            if(!vis[v[e]]){ 
                vis[v[e]] = true; 
                q.push(v[e]); 
            } 
        } 
    } 

 
int main(){ 
    int T,cas=1; 
    scanf("%d",&T); 
    while(T--){ 
        read_graph(); 
        SPFA(beg); 
        printf("Case #%d: ",cas++); 
        if(d[end]!=INF) printf("%d\n", d[end]); 
        else puts("unr

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,