PAT甲题题解-1003. Emergency (25)-最短路径+路径数目

给出n个城市,m条边,起始点c1和目的点c2
接下来给出n个城市的队伍数
以及m条双向边
问你求c1到c2的所有最短路径数目,以及其中经过的最多队伍数

先最短路dijkstra,同时建立vector数组pre存储前驱节点
然后dfs求出路径,以及每条路径经过的队伍数,更新最大值即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define INF 0x3f3f3f
using namespace std;
const int maxn=505;
int n,m,c1,c2;
int team[maxn];
struct Edge{
    int to;
    int w;
    int next;
}edge[maxn*maxn];
int head[maxn];
int tot;
void add(int u,int v,int w){
    edge[tot].to=v;
    edge[tot].w=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void init(){
    memset(head,-1,sizeof(head));
    tot=0;
}

struct Node{
    int u;
    int dis;
    bool operator<(const Node tmp)const{
        return dis>tmp.dis;
    }
};
int dis[maxn];
int vis[maxn];
vector<int>pre[maxn];
void dijkstra(int s,int t){
    for(int i=0;i<maxn;i++){
        dis[i]=INF;
        pre[i].clear();
        vis[maxn]=0;
    }
    priority_queue<Node>q;
    Node tmp;
    tmp.u=s;
    tmp.dis=dis[s]=0;
    q.push(tmp);
    while(!q.empty()){
        tmp=q.top();
        q.pop();
        vis[tmp.u]=1;
        int u=tmp.u;
        if(u==t)
            break;
        for(int k=head[u];k!=-1;k=edge[k].next){
            int v=edge[k].to;
            if(!vis[v]){
                if(dis[u]+edge[k].w<dis[v]){
                    dis[v]=dis[u]+edge[k].w;
                    tmp.u=v;
                    tmp.dis=dis[v];
                    q.push(tmp);
                    pre[v].clear();
                    pre[v].push_back(u);
                }
                else if(dis[u]+edge[k].w==dis[v]){
                    /*
                    原先下面的没有注释掉,导致有样例错误。。。
                    这样会导致点v会在队列里出现两多次,也就取出多次
                    这样会出现重复的路径,影响最短路径数
                    */
                    //tmp.u=v;
                    //tmp.dis=dis[v];
                    //q.push(tmp);
                    pre[v].push_back(u);
                }
            }
        }
    }
}
vector<int>path;
int maxsum=0;
int cnt=0;
void dfs(int u){
    if(pre[u].size()==0){
        path.push_back(u);
        cnt++;
        int sum=0;
        for(int i=0;i<path.size();i++){
            int u=path[i];
            sum+=team[u];
//printf("%d<-",u);
        }
//printf("
");
        if(sum>maxsum){
            maxsum=sum;
        }
        path.pop_back();
        return;
    }
    path.push_back(u);
    for(int i=0;i<pre[u].size();i++){
        dfs(pre[u][i]);
    }
    path.pop_back();
}
int main()
{
    int u,v,w;
    init();
    scanf("%d %d %d %d",&n,&m,&c1,&c2);
    for(int i=0;i<n;i++){
        scanf("%d",&team[i]);
    }
    for(int i=0;i<m;i++){
        scanf("%d %d %d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }
    dijkstra(c1,c2);
    dfs(c2);
    printf("%d %d
",cnt,maxsum);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/chenxiwenruo/p/6735714.html