样例输入:
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
样例输出:
2 4
思路:
这是一个最短路的题,但要求多了一些,要求我们统计最短路条数,若有多条最短路,需要输出能获得营救队伍最多的值。故需要我们在更新两个变量。
ans[i]表示到该城市的救援队总数,num[i]表示到该城市的线路数目
看了下别人的代码,好像都是朴素版本的,所以写了一个堆优化版本的。
(菜鸡没仔细看这题是稠密图还是稀疏图,纯粹只是习惯了写堆优化版本的qaq)
核心代码
if(d[e.to] > d[v] + e.cost)
{
d[e.to] = d[v] + e.cost;
ans[e.to] = ans[v] + re[e.to];
num[e.to] = num[v];
pq.push(pi(d[e.to] , e.to));
}
else if(d[e.to] == d[v] + e.cost)
{
ans[e.to] = max(ans[e.to] , ans[v] + re[e.to]);
num[e.to] += num[v];
}
代码
//PAT 1003 Emergency (25 分)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define FOR(i,a,n) for (int i=a;i<n;i++)
#define FRO(i,n,a) for (int i=n;i>a;i--)
#define mst(a,i) memset(a,i,sizeof a)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pi pair<int,int>
#define eps 1e-6
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
const int mod = 1000000007;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
const int N = 1e5+6;
// const int MAXN=1e4;
// int a[N]={};
// int b[N]={};
int n , m;
int st , ed;
int ans[520] , num[520];//num 存路的数目,ans存救援队总数
struct edge
{
int to , cost;
};
vector<edge> G[520];
int d[520];
int re[520];//re表示该城市救援队数目
void solve()
{
priority_queue<pair<int , int> , vector<pair<int,int> > , greater<pair<int,int> > > pq;
pq.push(pair<int,int>(0,st));
d[st] = 0;ans[st] = 0;num[st] = 1;
ans[st] += re[st];
while(!pq.empty())
{
pair<int,int> p = pq.top();
pq.pop();
int v = p.second;
if(d[v] < p.first)continue;
for(int i = 0 ; i < G[v].size() ; i++)
{
edge e = G[v][i];
if(d[e.to] > d[v] + e.cost)
{
d[e.to] = d[v] + e.cost;
ans[e.to] = ans[v] + re[e.to];
// cout << "e.to" << e.to << ' ' << ans[v] << '+' << re[e.to] << '\n';
num[e.to] = num[v];
pq.push(pi(d[e.to] , e.to));
}
else if(d[e.to] == d[v] + e.cost)
{
ans[e.to] = max(ans[e.to] , ans[v] + re[e.to]);
num[e.to] += num[v];
// cout << "e.to" << e.to << ' ' << ans[v] << '+' << re[e.to] << '\n';
}
}
}
}
int main(){
IOS
cin >> n >> m >> st >> ed;
memset(G,0,sizeof(G));mst(d,INF);memset(re,0,sizeof(re));
memset(ans,0,sizeof(ans));mst(num,0);
for(int i = 0 ; i < n ; i++)cin >> re[i];
int a , b ,c;
edge e;
for(int i = 0 ; i < m ; i++)
{
cin >> a >> b >> c;
e.cost = c;e.to = b;
edge e2; e2.cost = c; e2.to = a;
G[a].push_back(e);
G[e.to].push_back(e2);
}
solve();
// FOR(i,0,n )cout << G[i][0].to << ' ' << G[i][0].cost;
// FOR(i,0,n)cout << d[i] << ' ';
cout << num[ed] << ' ' << ans[ed];
return 0;
}