题解
确定起点和终点,求救援人数最长,路径最短的路径,只需要集群算法中优先队列中重载比较符修改一下就就行,由于数据量很小,所以输出路径的时候搜索就行(最优解唯一)
code
#include<bits/stdc++.h>
using namespace std;
struct node
{
int to,val;
};
vector<node> G[505];
int people[505]={0};
int help[505]={0};
int dis[505];
int path[505]={0};
int vis[505]={0};
stack<int> st;
int flag=0;
int n,m,s,d;
struct fresh
{
int to,pre,val;
bool operator<(const fresh &b)const
{
if(val!=b.val)return val>b.val;//dis
else return help[pre]+people[to]<help[b.pre]+people[b.to];//help
}
};
void ss(int walk,int cure,int now)
{
if(walk==0&&cure==0)
{
if(now!=d) return;
flag=1;
st.push(now);
return ;
}
if(walk<=0||cure<=0||now==d) return;
for(auto next:G[now])
{
int to=next.to,val=next.val;
if(!vis[to])
{
vis[to]=1;
ss(walk-val,cure-people[to],to);
vis[to]=0;
}
if(flag)
{
st.push(now);
return ;
}
}
}
int main()
{
memset(dis,0x3f,sizeof dis);
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++) cin>>people[i];
for(int i=1;i<=m;i++)
{
int x,y,c;
cin>>x>>y>>c;
G[x].push_back({y,c});
G[y].push_back({x,c});
}
priority_queue<fresh> q;
q.push({s,s,0});
path[s]=1;
while(q.size())
{
int now=q.top().to,pre=q.top().pre,val=q.top().val;
q.pop();
if(dis[now]<val) continue;
else if(dis[now]==val)
{
path[now]+=path[pre];
continue;
}
dis[now]=val;
path[now]=path[pre];
help[now]=help[pre]+people[now];
for(auto next:G[now]) q.push({next.to,now,next.val+dis[now]});
}
cout<<path[d]<<" "<<help[d]<<endl;
ss(dis[d],help[d]-people[s],s);
while(st.size())
{
cout<<st.top();
st.pop();
if(st.size()) cout<<" ";
}
return 0;
}
标签:pre,救援,val,people,int,top,001,L2,505
From: https://www.cnblogs.com/pure4knowledge/p/18143490