首页 > 代码库 > UVA10917 Walk Through the Forest

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+7using 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<<"\n";        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\n";            cout<<ans<<endl;        }        else{            dfs1(u);dfs2(v);cout<<endl;            cout<<u+1<<"\n"<<ans<<endl;        }    }    //fclose(stdout);    return 0;}

 

UVA10917 Walk Through the Forest