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;
}
原文地址:https://www.cnblogs.com/Noevon/p/7324393.html