zoukankan      html  css  js  c++  java
  • UVA10917 Walk Through the Forest

    题意:一个人从A到B,只能走这样的边回家,起点到B的距离比终点到B的距离更短,问有几条路径能回家

    题解:水题,先从B开始来一遍dijstra,得到所有的满足条件的边,就是一个DAG,记忆化搜索+DP就可以

    #include <bits/stdc++.h>
    #define ll long long
    #define maxn 100010
    #define INF 1e9+7
    using namespace std;
    struct edge{
        int from,to,dist;
    };
    struct node{
        int d,u;
        bool operator<(const node& a) const{
            return d>a.d;
        }
    };
    struct dij{
        int n,m;
        vector<int >G[maxn];//从0开始
        vector<edge>edges;
        bool done[maxn];
        int d[maxn]; //距离
        int p[maxn]; //上一条边,端点判断
        void init(int x){//边数,初始化
            n = x;
            for(int i=0;i<n;i++) G[i].clear();
            edges.clear();
        }
        void add(int a,int b,int w){
            edges.push_back((edge){a,b,w});
            m = edges.size();
            G[a].push_back(m-1);
        }
        void dijstra(int st){//计算最短路
            for(int i=0;i<n;i++) d[i] = INF;
            memset(done, 0, sizeof(done));
            d[st] = 0;
            priority_queue<node>q;
            q.push((node){0, st});
            while(!q.empty()){
                node fi = q.top();q.pop();
                int u = fi.u;
                if(done[u]) continue;
                done[u] = 1;
                for(int i=0;i<G[u].size();i++){
                    edge& e = edges[G[u][i]];
                    if(e.dist+d[u]<d[e.to]){
                        d[e.to] = d[u]+e.dist;
                        p[e.to] = G[u][i];
                        q.push((node){d[e.to], e.to});
                    }
                }
            }
        }
    }ds, de;
    int s,e;
    void dfs1(int a){
        if(a == s){
            cout<<a+1;
            return ;
        }
        edge e = ds.edges[ds.p[a]];
        dfs1(e.from);
        cout<<" "<<a+1;
    }
    void dfs2(int a){
        if(a == e){
            cout<<" "<<a+1;
            return ;
        }
        edge e = de.edges[de.p[a]];
        cout<<" "<<a+1;
        dfs2(e.from);
    }
    int main(){
        int n, m, k, a, b, c, aaa=0;
        while(cin>>n>>s>>e){
            if(aaa++) cout<<"
    ";
            s--,e--;
            ds.init(n);de.init(n);
            cin>>m;
            for(int i=0;i<m;i++){
                cin>>a>>b>>c;
                a--,b--;
                ds.add(a, b, c);ds.add(b, a, c);
                de.add(a, b, c);de.add(b, a, c);
            }
            ds.dijstra(s); de.dijstra(e);
            cin>>k;
            int u=-1,v=-1, ans = ds.d[e];
            for(int i=0;i<k;i++){
                cin>>a>>b>>c;
                a--,b--;
                if(ds.d[a]+c+de.d[b] < ans){
                    ans = ds.d[a]+c+de.d[b];
                    u = a;
                    v = b;
                }
                if(ds.d[b]+c+de.d[a] < ans){
                    ans = ds.d[b]+c+de.d[a];
                    u = b;
                    v = a;
                }
            }
            if(u == -1){
                dfs1(e);cout<<endl;
                cout<<"Ticket Not Used
    ";
                cout<<ans<<endl;
            }
            else{
                dfs1(u);dfs2(v);cout<<endl;
                cout<<u+1<<"
    "<<ans<<endl;
            }
        }
        //fclose(stdout);
        return 0;
    }
  • 相关阅读:
    小波变换的引入,通俗易懂
    Leetcode 437. Path Sum III
    Leetcode 113. Path Sum II
    Leetcode 112 Path Sum
    Leetcode 520 Detect Capital
    Leetcode 443 String Compression
    Leetcode 38 Count and Say
    python中的生成器(generator)总结
    python的random模块及加权随机算法的python实现
    leetcode 24. Swap Nodes in Pairs(链表)
  • 原文地址:https://www.cnblogs.com/Noevon/p/7324393.html
Copyright © 2011-2022 走看看