• hdu 1874(最短路 Dilkstra +优先队列优化+spfa)


    畅通工程续

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 50537    Accepted Submission(s): 18852

    Problem Description
    某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
    现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
    Input
    本题目包含多组数据,请处理到文件结束。
    每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
    接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
    再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
    Output
    对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
    Sample Input
    3 3
    0 1 1
    0 2 3
    1 2 1
    0 2
    3 1
    0 1 1
    1 2
    Sample Output
    2
    -1
    Author
    linle
    Source
     
    1》Dijkstra算法求最短路
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<set>
    #include<vector>
    #include<cstdlib>
    #include<string>
    #define eps 0.000000001
    typedef long long ll;
    typedef unsigned long long LL;
    using namespace std;
    const int N=300+10;
    const int INF=0x3f3f3f3f;
    int n,m;
    int mp[N][N];
    int vis[N];
    int dis[N];
    void init(){
       // memset(dis,0,sizeof(dis));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<N;i++)
        for(int j=0;j<N;j++){mp[i][j]=INF;
        }
    
    }
    void Dijkstra(int v,int e){
        dis[v]=0;
        vis[v]=1;
        int pos;
        for(int i=0;i<n;i++)dis[i]=mp[v][i];
        for(int i=1;i<n;i++){
            int minn=INF;
            for(int j=0;j<n;j++){
                if(dis[j]<minn&&vis[j]==0){
                    pos=j;
                    minn=dis[j];
                }
            }
            vis[pos]=1;
            for(int j=0;j<n;j++){
                if(dis[pos]+mp[pos][j]<dis[j]&&vis[j]==0)
                    dis[j]=dis[pos]+mp[pos][j];
            }
        }
    }
    int main(){
        while(scanf("%d%d",&n,&m)!=EOF){
            init();
            for(int i=0;i<m;i++){
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                if(z<mp[x][y])
                mp[x][y]=mp[y][x]=z;
            }
            int v0,v;
            scanf("%d%d",&v0,&v);
             if(v0==v){
                cout<<0<<endl;
                continue;
            }
            Dijkstra(v0,v);
            if(dis[v]==INF)cout<<-1<<endl;
            else
                cout<<dis[v]<<endl;
    
        }
    }

     Dijkstra +优先队列优化 

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<map>
     8 #include<stack>
     9 #include<set>
    10 #include<vector>
    11 #include<cstdlib>
    12 #include<string>
    13 #define eps 0.000000001
    14 typedef long long ll;
    15 typedef unsigned long long LL;
    16 using namespace std;
    17 const int N=1000+10;
    18 const int INF=0x3f3f3f3f;
    19 int m,n;
    20 struct node{
    21     int to,next,w;
    22     bool operator<(const node &a)const{
    23         return w>a.w;
    24     }
    25 }edge[N];
    26 int head[N];
    27 int t;
    28 int vis[N],dis[N];
    29 void init(){
    30     memset(vis,0,sizeof(vis));
    31     t=0;
    32     memset(head,-1,sizeof(head));
    33     for(int i=0;i<N;i++)dis[i]=INF;
    34 }
    35 void add(int u,int v,int w){
    36     edge[t].to=v;
    37     edge[t].w=w;
    38     edge[t].next=head[u];
    39     head[u]=t++;
    40 }
    41 int Dijkstra(int x){
    42     dis[x]=0;
    43     node t1,t2;
    44     priority_queue<node>q;
    45     t1.to=x;
    46     q.push(t1);
    47     while(!q.empty()){
    48         t1=q.top();
    49         q.pop();
    50         int u=t1.to;
    51         if(vis[u]==1)continue;
    52         vis[u]=1;
    53         for(int i=head[u];i!=-1;i=edge[i].next){
    54             int v=edge[i].to;
    55             if(vis[v]==0&&dis[v]>dis[u]+edge[i].w){
    56                 dis[v]=dis[u]+edge[i].w;
    57                 t2.to=v;
    58                 t2.w=dis[v];
    59                 q.push(t2);
    60             }
    61         }
    62     }
    63 
    64 }
    65 int main(){
    66     while(scanf("%d%d",&n,&m)!=EOF){
    67         init();
    68         for(int i=0;i<m;i++){
    69             int u,v,w;
    70             scanf("%d%d%d",&u,&v,&w);
    71             add(u,v,w);
    72             add(v,u,w);
    73         }
    74         int x,y;
    75         scanf("%d%d",&x,&y);
    76         Dijkstra(x);
    77         if(dis[y]==INF)cout<<-1<<endl;
    78         else
    79             cout<<dis[y]<<endl;
    80 
    81     }
    82 }

    spfa算法求最短路

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<string.h>
     7 #include<set>
     8 #include<vector>
     9 #include<queue>
    10 #include<stack>
    11 #include<map>
    12 #include<cmath>
    13 typedef long long ll;
    14 typedef unsigned long long LL;
    15 using namespace std;
    16 const double PI=acos(-1.0);
    17 const double eps=0.0000000001;
    18 const int INF=0x3f3f3f3f;
    19 const int N=100000+10;
    20 int n,m;
    21 struct node{
    22     int w,next,to;
    23 }edge[N<<1];
    24 int head[N];
    25 int tot;
    26 void init(){
    27     memset(head,-1,sizeof(head));
    28     tot=0;
    29 }
    30 void add(int u,int v,int w){
    31     edge[tot].to=v;
    32     edge[tot].w=w;
    33     edge[tot].next=head[u];
    34     head[u]=tot++;
    35 }
    36 int dis[N];
    37 int vis[N];
    38 void spfa(int s){
    39     queue<int>q;
    40     memset(dis,INF,sizeof(dis));
    41     dis[s]=0;
    42     memset(vis,0,sizeof(vis));
    43     q.push(s);
    44     vis[s]=1;
    45     while(!q.empty()){
    46         int x=q.front();
    47         q.pop();
    48         vis[x]=0;
    49         for(int i=head[x];i!=-1;i=edge[i].next){
    50             int v=edge[i].to;
    51             if(dis[x]+edge[i].w<dis[v]){
    52                 dis[v]=dis[x]+edge[i].w;
    53                 if(vis[v])continue;
    54                 vis[v]=1;
    55                 q.push(v);
    56             }
    57 
    58         }
    59     }
    60 }
    61 int main(){
    62     while(cin>>n>>m){
    63         init();
    64         for(int i=0;i<m;i++){
    65             int u,v,w;
    66             scanf("%d%d%d",&u,&v,&w);
    67             add(u,v,w);
    68             add(v,u,w);
    69         }
    70         int u,v;
    71         scanf("%d%d",&u,&v);
    72         spfa(u);
    73         if(dis[v]==INF)cout<<-1<<endl;
    74         else{
    75             cout<<dis[v]<<endl;
    76         }
    77     }
    78 }
     
  • 相关阅读:
    浅谈.NET下的多线程和并行计算系列文章索引
    浅谈.NET下的多线程和并行计算(六)线程池基础下
    浅谈.NET下的多线程和并行计算(八)Winform中多线程编程基础上
    项目优化经验——垃圾回收导致的性能问题
    浅谈.NET下的多线程和并行计算(五)线程池基础上
    站点静态资源优化合并解决方案
    浅谈.NET下的多线程和并行计算(二)线程基本知识
    浅谈.NET下的多线程和并行计算(十二)CLR via C#第三版阅读笔记(1)
    原谅我的说谎
    索爱手机GPRS的OTA设置[转]
  • 原文地址:https://www.cnblogs.com/Aa1039510121/p/6551572.html
Copyright © 2020-2023  润新知