zoukankan      html  css  js  c++  java
  • 最短路径 | 1111

    最短路径已经考腻了,已经在往模拟的趋势上发展。今天顺便还练习了一下前向星,感觉很好用,以后都用前向星了。

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 1010
    #define MAX (1<<30)-1
    #define V vector<int>
    
    using namespace std;
    
    int head[LEN];
    int vis[LEN];
    struct edge{
        int to,next,dist,Time;
    }mp[LEN*LEN];
    int eID=0;
    void add(int u,int v,int dist,int Time){
        mp[eID].to=v;
        mp[eID].dist=dist;
        mp[eID].Time=Time;
        mp[eID].next=head[u];
        head[u]=eID++;
    }
    
    int N,M,s,e;
    int dist[LEN];
    int Time[LEN];
    int pre[LEN];
    int cnt[LEN];
    vector<int> path1;
    vector<int> path2;
    int minDist;
    int minTime;
    
    void printPath(vector<int>& p){
        int sz=p.size();
        int i;
        FF(i,sz){
            O("%d",p[i]);
            if(i!=sz-1) O(" -> ");
        }
        puts("");
    }
    
    bool pathEqual(){
        if(path1.size()!=path2.size()) return false;
        int i;
        FF(i,path1.size()){
            if(path1[i]!=path2[i]) return false;
        }
        return true;
    }
    
    void dij_1(){//获得最短路径。如果最短路径不唯一,输出最快路径 
        fill(dist,dist+LEN,MAX);
        fill(Time,Time+LEN,MAX);
        fill(vis,vis+LEN,0);
        fill(pre,pre+LEN,-1);
        dist[s]=0;
        Time[s]=0;
        int i;
        while(1){
            int u=-1,min_d=MAX;
            FF(i,N) if(!vis[i] && dist[i]<min_d){
                min_d=dist[i];
                u=i;
            }
            if(u<0) break;
            vis[u]=1;
            for(i=head[u];~i;i=mp[i].next){
                int to=mp[i].to;
                if(!vis[to]){//s->u + u->to 
                    if(dist[u]+mp[i].dist<dist[to] || (dist[u]+mp[i].dist==dist[to] && Time[u]+mp[i].Time<Time[to])){
                        dist[to]=dist[u]+mp[i].dist;
                        Time[to]=Time[u]+mp[i].Time;
                        pre[to]=u;
                    }
                }
            }
        }
        i=e;
        while(i>=0){
            path1.insert(path1.begin(),i);
            i=pre[i];
        }
        minDist=dist[e];
    }
    
    void dij_2(){//获得最快路径。如果路径不唯一,输出经过点最少的路径 
        fill(Time,Time+LEN,MAX);
        fill(vis,vis+LEN,0);
        fill(pre,pre+LEN,-1);
        Time[s]=0;
        int i;
        while(1){
            int u=-1,min_d=MAX;
            FF(i,N) if(!vis[i] && Time[i]<min_d){
                min_d=Time[i];
                u=i;
            }
            if(u<0) break;
            vis[u]=1;
            for(i=head[u];~i;i=mp[i].next){
                int to=mp[i].to;
                if(!vis[to]){//s->u + u->to 
                    if(Time[u]+mp[i].Time<Time[to] || (Time[u]+mp[i].Time==Time[to] && cnt[u]+1<cnt[to])){
                        Time[to]=Time[u]+mp[i].Time;
                        cnt[to]=cnt[u]+1;
                        pre[to]=u;
                    }
                }
            }
        }
        i=e;
        while(i>=0){
            path2.insert(path2.begin(),i);
            i=pre[i];
        }
        minTime=Time[e];
    }
    
    int main(){
    //    freopen("I:\pat\最短路径\1111_2.txt","r",stdin);
        memset(head,-1,sizeof(head));
        I("%d%d",&N,&M);
        int i,j,u,v,o,d,t;
        FF(i,M){
            I("%d%d%d%d%d",&u,&v,&o,&d,&t);
            add(u,v,d,t);
            if(o==0)    //不是单程路 
                add(v,u,d,t);
        }
        I("%d%d",&s,&e);
        dij_1();
        dij_2();
        if(pathEqual()){
            O("Distance = %d; Time = %d: ",minDist,minTime);
            printPath(path1);
        }else{
            O("Distance = %d: ",minDist);
            printPath(path1);
            O("Time = %d: ",minTime);
            printPath(path2);
        }
        return 0;
    }
  • 相关阅读:
    poj2955(区间dp)
    poj3280(区间dp)
    poj1651(区间dp)
    hdu5001(概率dp)
    hdu4389(数位dp)
    hdu4352(数位dp)
    CF 148D(概率dp)
    zoj3329(概率dp)
    POJ1028 Web Navigation
    POJ1027 The Same Game
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8593037.html
Copyright © 2011-2022 走看看