• hdu3499(分层图最短路 or 反向建图)


    传送门

    方法一:分层图

    #include<bits/stdc++.h>
    #define per(i,a,b) for(int i=a;i<=b;i++)
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    const ll inf =23333333333333333LL;
    const double eps=1e-8;
    int T;
    int read(){
        char ch=getchar();
        int res=0,f=0;
        while(ch<'0' || ch>'9'){f=(ch=='-'?-1:1);ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();}
        return res*f;
    }
    // ------------------------head
    const int siz=100005;
    map<string,int> mp;
    int mcnt=0,n,m;
    int d;
    char x[15],y[15],schar[15],echar[15];
    int head[siz],Enum=0;
    ll dis[siz][2];
    bool vis[siz][2];
    int st,ed;
    struct Edge{int to,w,ne;}edge[siz*5];
    void add_edge(int a,int b,int c){
        edge[Enum].to=b;
        edge[Enum].w=c;
        edge[Enum].ne=head[a];
        head[a]=Enum++;
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        Enum=0;
        mp.clear();
        mcnt=0;
    } 
    int _hash(char *s){//char*作为实参传给string形参会自动变
        if(mp.count(s)>0)return mp[s];//string作为形参传给char*要转变s.c_str();
        else return mp[s]=mcnt++;
    }
    struct Qnode{
        int u;
        ll _dis;
        int layer;//位于分层图的哪层
        Qnode(){}
        Qnode(ll a,int b,int c):_dis(a),u(b),layer(c){}
        bool operator<(const Qnode&rhs)const{return _dis>rhs._dis;}//一定要加const
    };
    void Dijkstra(){
        priority_queue<Qnode>que;
        while(!que.empty())que.pop();
        memset(vis,false,sizeof(vis));
        per(i,0,n){dis[i][0]=inf;dis[i][1]=inf;}
        que.push(Qnode(0LL,st,0));
        dis[st][0]=0; //注意初始化的是st点,而不是0点,这里没注意到!!!
        vis[st][0]=true;
        Qnode tmp;
        while(!que.empty()){
            tmp=que.top();que.pop();
            int u=tmp.u,layer=tmp.layer;
            ll _dis=tmp._dis;
            //printf("dis:%lld   u:%d   layer:%d
    ",_dis,u,layer);//
            vis[u][layer]=true;
            //if(u==ed && layer==1)return;//
            //printf("dis[%d]:%lld
    ",u,dis[u][0]);//
            for(int i=head[u];i!=-1;i=edge[i].ne){
                int v=edge[i].to,w=edge[i].w;
                //printf("w:%d
    ",w);exit(0);//
                //printf("v:%d  
    ");//
                //printf("dis[u][layer]:%lld
    ",dis[u][layer]);//
                //printf("dis[v][layer+1]:%lld  dis[v][layer]:%lld  w:%d
    ",dis[v][layer+1],dis[v][layer],w);//
                //if(dis[v][layer+1]>dis[u][layer]+w/2)printf("cas1 ok
    ");else printf("cas1 no
    ");//
                if(layer<1 && !vis[v][layer+1] &&dis[v][layer+1]>dis[u][layer]+w/2){
                    dis[v][layer+1]=dis[u][layer]+w/2;
                    //printf("Push  v%d  dis:%lld  layer:%d
    ",v,dis[v][layer],layer+1);//
                    que.push(Qnode(dis[v][layer+1],v,layer+1));
                }
                if(!vis[v][layer] && dis[v][layer]>dis[u][layer]+w){
                    dis[v][layer]=dis[u][layer]+w;
                    que.push(Qnode(dis[v][layer],v,layer));
                }
            }
        }
    }
    
    int main()
    {
        while(scanf("%d %d",&n,&m)!=EOF){
            init();
            per(i,1,m){
                scanf("%s %s %d",x,y,&d);
                int xn=_hash(x),yn=_hash(y);
                //printf("%s:%d %s:%d d:%d
    ",x,xn,y,yn,d);//
                add_edge(xn,yn,d);
            }
            scanf("%s %s",schar,echar);
            if(mp.count(schar)==0||mp.count(echar)==0){printf("-1
    ");continue;}
            st=_hash(schar);ed=_hash(echar);
            //printf("%s:%d  %s:%d
    ",schar,st,echar,ed);//
            Dijkstra();
            ll ans=min(dis[ed][0],dis[ed][1]);
            if(ans==inf)printf("-1
    ");
            else printf("%lld
    ",ans);
        }
    
        return 0;
    }
    View Code

    方法二:反向建图

    使用封装+引用 ,  因为这里dijkstra()两次,不封装就要每种变量开两次,代码看上去就会有点乱QwQ

    #include<bits/stdc++.h>
    #define per(i,a,b) for(int i=a;i<=b;i++)
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    const ll inf =23333333333333333LL;
    const double eps=1e-8;
    int T;
    int read(){
        char ch=getchar();
        int res=0,f=0;
        while(ch<'0' || ch>'9'){f=(ch=='-'?-1:1);ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();}
        return res*f;
    }
    // ------------------------head
    #define siz 100010
    int n,m;
    struct Edge{
        int from,to,ne;
        ll dis;
        Edge(){}
        Edge(int a,int b,int c,int d):dis(a),from(b),to(c),ne(d){}
    };
    struct HeapNode{
        ll dis;
        int u;
        HeapNode(){}
        HeapNode(ll a,int b):dis(a),u(b){}
        bool operator<(const HeapNode&rhs)const{
            return dis>rhs.dis;
        }
    };
    struct Dijkstra{
        int n,Enum;
        int head[siz];
        Edge edge[siz*5];
        ll dis[siz];
        bool vis[siz];
    
        void init(){
            Enum=0;
            memset(head,-1,sizeof(head));
        }
        void add_edge(int from,int to,int d){
            edge[Enum]=Edge(d,from,to,head[from]);
            head[from]=Enum++;
        }
        void dijkstra(int st){
            priority_queue<HeapNode>que;
            while(!que.empty())que.pop();
            memset(vis,false,sizeof(vis));
            per(i,0,n-1)dis[i]=(i==st?0:inf);
            //printf("dis:");//
            //per(i,0,n-1)printf("%lld ",dis[i]);printf("
    ");exit(0);//
            vis[st]=true;
            que.push(HeapNode(0LL,st));
            while(!que.empty()){
                HeapNode tmp=que.top();que.pop();
                int u=tmp.u;
                //printf("u:%d dis:%lld
    ",u,tmp.dis);//
                //if(vis[u]==true)continue;
                for(int i=head[u];i!=-1;i=edge[i].ne){
                    int v=edge[i].to,w=edge[i].dis;
                    //printf("v:%d  w:%d  dis[u]:%lld  dis[v]:%lld
    ",v,w,dis[u],dis[v]);//
                    if(dis[v]>dis[u]+w){
                        dis[v]=dis[u]+w;
                        //printf("Push v:%d dis[v]:%lld
    ",v,dis[v]);//
                        que.push(HeapNode(dis[v],v));
                    }
                }
            }
        }
    }DJ1,DJ2;
    map<string,int>mp;
    int mp_cnt=0;
    int ID(char*s){
        if(mp.count(s)>0)return mp[s];
        else return mp[s]=mp_cnt++;
    }
    
    int main()
    {
        //freopen("Data_In.txt","r",stdin);
        char x[15],y[15],schar[15],echar[15];
        int xn,yn;
        int d,st,ed;
        while(scanf("%d %d",&n,&m)!=EOF){
            mp.clear();
            mp_cnt=0;
            DJ1.init();DJ2.init();
            DJ1.n=DJ2.n=n;
            per(i,0,m-1){
                scanf("%s %s %d",x,y,&d);
                xn=ID(x);yn=ID(y);
                DJ1.add_edge(xn,yn,d);
                DJ2.add_edge(yn,xn,d);
            }
            scanf("%s %s",schar,echar);
            if(mp.count(schar)==0||mp.count(echar)==0){
                printf("-1
    ");continue;
            }
            st=ID(schar);ed=ID(echar);
            DJ1.dijkstra(st);DJ2.dijkstra(ed);
            //per(i,0,n-1)printf("%lld ",DJ1.dis[i]);printf("
    ");return 0;//
            if(DJ1.dis[ed]==inf){
                printf("-1
    ");continue;
            }
            ll ans=inf;
            for(int i=0;i<DJ1.Enum;i++){
                int u=DJ1.edge[i].from,v=DJ1.edge[i].to;
                int d=DJ1.edge[i].dis;
                ans=min(ans,DJ1.dis[u]+DJ2.dis[v]+d/2);
            }
            printf("%lld
    ",ans);
        }
    
        return 0;
    }
    View Code

    我的未ac版

    #include<bits/stdc++.h>
    #define per(i,a,b) for(int i=a;i<=b;i++)
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    const ll inf =23333333333333333LL;
    const double eps=1e-8;
    int T;
    int read(){
        char ch=getchar();
        int res=0,f=0;
        while(ch<'0' || ch>'9'){f=(ch=='-'?-1:1);ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();}
        return res*f;
    }
    // ------------------------head
    #define siz 100005
    int n,m;
    int head1[siz],head2[siz],Enum1,Enum2;
    ll dis1[siz],dis2[siz];
    bool vis1[siz],vis2[siz];
    struct Edge{
        int from,to,ne;
        int dis;
    }edge1[siz*5],edge2[siz*5]; 
    map<string,int>mp;
    int mp_cnt=0;
    void init(){
        memset(head1,-1,sizeof(head1));
        memset(head2,-1,sizeof(head2));
        Enum1=Enum2=0;
        mp_cnt=0;
        mp.clear();
    }
    void add_edge(int a,int b,int c,int head[],Edge edge[],int &E){
        edge[E].from=a;
        edge[E].to=b;
        edge[E].dis=c;
        edge[E].ne=head[a];
        head[a]=E++;
    }
    int _hash(char s[]){
        if(mp.count(s)>0)return mp[s];
        else return mp[s]=mp_cnt++;
    }
    struct Qnode{
        int u;
        ll _dis;
        Qnode(){}
        Qnode(ll a,int b):_dis(a),u(b){}
        bool operator<(const Qnode&rhs)const{return _dis>rhs._dis;}
    };
    void Dijkstra(int st,int head[],Edge edge[],ll dis[],bool vis[]){
        memset(vis,false,sizeof(vis));
        priority_queue<Qnode>que;
        while(!que.empty())que.pop();
        per(i,0,n-1)dis[i]=inf;
        dis[st]=0;
        vis[st]=true;
        que.push(Qnode(0LL,st));
        Qnode tmp;
        while(!que.empty()){
            tmp=que.top();que.pop();
            int u=tmp.u;
            ll _dis=tmp._dis;
            //printf("u:%d dis:%lld
    ",u,_dis);//
            vis[u]=true;
            for(int i=head[u];i!=-1;i=edge[i].ne){
                int v=edge[i].to,w=edge[i].dis;
                if(vis[v]==false && dis[v]>_dis+w){
                    dis[v]=_dis+w;
                    que.push(Qnode(dis[v],v));
                }
            }
        }
    }
    
    int main()
    {
        freopen("Data_In.txt","r",stdin);
        char x[15],y[15],schar[15],echar[15];
        int d,st,ed;
        while(scanf("%d %d",&n,&m)!=EOF){
            init();
            per(i,1,m){
                scanf("%s %s %d",x,y,&d);
                int xn=_hash(x),yn=_hash(y);
                //printf("%s:%d %s:%d d:%d
    ",x,xn,y,yn,d);//
                add_edge(xn,yn,d,head1,edge1,Enum1);
                add_edge(yn,xn,d,head2,edge2,Enum2);
            }
            scanf("%s %s",schar,echar);
            if(mp.count(schar)==0||mp.count(echar)==0){printf("-1
    ");continue;}
            st=_hash(schar);ed=_hash(echar);
            //printf("st:%d  ed:%d
    ",st,ed);//
            //printf("%s:%d  %s:%d
    ",schar,st,echar,ed);//
            Dijkstra(st,head1,edge1,dis1,vis1);
            Dijkstra(ed,head2,edge2,dis2,vis2);
            //per(i,0,n-1)printf("%lld
    ",dis1[i]);printf("
    ");//
            ll ans=inf;
            if(dis1[ed]==inf){printf("-1
    ");continue;}
            for(int i=0;i<Enum1;i++){
                int from=edge1[i].from,to=edge1[i].to,_dis=edge1[i].dis;
                ans=min(ans,dis1[from]+dis2[to]+_dis/2);
            }
            //if(ans==inf){printf("-1
    ");continue;}
            printf("%lld
    ",ans);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    Nginx-limit_req限速配置示例
    Linux-配置虚拟IP实例
    jQuery中获取a标签的值
    js时间格式化
    a标签与js的冲突
    spring MVC页面的重定向
    EL表达式遍历集合获取下标
    商城项目之实战-购物车模块
    js中得计算问题算式结果拼接成字符串怎么解决
    js中数值类型相加变成拼接字符串的问题
  • 原文地址:https://www.cnblogs.com/WindFreedom/p/9597556.html
Copyright © 2020-2023  润新知