天梯赛 L2-001 紧急救援

L2-001 紧急救援 (25 分)

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。

输入格式:

输入第一行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0 ~ (N−1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。

第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。

输出格式:

第一行输出最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出结尾不能有多余空格。

输入样例:

4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

输出样例:

2 60
0 1 3

dijkstra算法变形,AC的C++程序如下:

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
using namespace std;
const int maxn=505;
const int inf=0x3f3f3f3f;
int n,m,s,d;
int visit[maxn],dist[maxn],pre[maxn];
int sum[maxn];//记录某个点的方案数
int person[maxn],save[maxn];//记录每个点救援队的数量和到达一个点所能召集救援队的总数 
struct edge
{
	int v,len;
	edge()
	{
	}
	edge(int v1,int l1)
	{
		v=v1,len=l1;
	}
};
vector<edge> g[maxn];
struct node1
{
    int u, cost;
    node1(int u1, int c)
    {
        u = u1;
        cost = c;
    }
    bool operator<(const node1 &s) const
    {
        return cost > s.cost;
    }
};
void dijkstra()
{
    priority_queue<node1> q;
    for (int i = 0; i <n; i++)
    {
        visit[i] = 0, dist[i] = inf;
        sum[i]=0,pre[i]=-1,save[i]=0;
    }
    dist[s] = 0,sum[s]=1,save[s]=person[s];
    q.push(node1(s, 0));
    while (!q.empty())
    {
        node1 f = q.top();
        q.pop();
        int u = f.u;
        if (visit[u]) continue;
        visit[u] = 1;
        for (int i = 0; i < (int)g[u].size(); i++)
        {
            int v = g[u][i].v;
            int temp = g[u][i].len;
            if (dist[v] > dist[u] + temp)
            {
                dist[v] = dist[u] + temp;
                sum[v]=sum[u];
                q.push(node1(v, dist[v]));
                save[v]=save[u]+person[v]; 
                pre[v]=u;
            }
            else if (dist[v] == dist[u] + temp)
            {
            	sum[v]+=sum[u];
                if (save[u]+person[v]>save[v])
                {
                    save[v]=save[u]+person[v];
                    pre[v]=u;
                }
            }
        }
    }
}
void print(int i) //打印路线 
{
   if(pre[i]!=-1)
   {
   	print(pre[i]);
   }
   if(i!=s) cout<<" ";
   cout<<i;
}
int main()
{
	cin>>n>>m>>s>>d;
	for(int i=0;i<n;i++)
	{
		cin>>person[i];
	}
	for(int i=0;i<m;i++)
	{
		int u,v,len;
		cin>>u>>v>>len;
		g[u].push_back(edge(v,len));
		g[v].push_back(edge(u,len));
	}
	dijkstra();
	cout<<sum[d]<<" "<<save[d]<<endl;
	print(d);
}

猜你喜欢

转载自blog.csdn.net/jinduo16/article/details/87271712