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;
    }
  • 相关阅读:
    SAP HANA中创建分析权限(Analytic Privilege)
    SAP HANA 中的决策表(Decision Table)
    SAP HANA procudure 创建用户
    数据挖掘与分析学习链接汇总
    Wpf 自定义窗体
    Winform里实现一个双击ListBox可以切换为TextBox编辑的效果
    一个从没见过的C# ?.语法
    VB.net怎么用Sub Main
    Office2010 帮助查看器遇到意外问题
    WcfService:单服务多契约接口以及用户名密码认证
  • 原文地址:https://www.cnblogs.com/Noevon/p/7324393.html
Copyright © 2011-2022 走看看