带有双重条件的最短路径问题
第二行包含n个空格分隔的正整数(不超过600),表示进入每个房间你的得分。
再接下来m行,每行3个空格分隔的整数x, y, z (0 <z<=200)表示道路,表示从房间x到房间y(双向)的道路,注意,最多只有一条道路连结两个房间, 你需要的时间为z。
输入保证从start到end至少有一条路径。
3 2 0 2 1 2 3 0 1 10 1 2 11
21 6
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
#define inf 1e17
#define maxn 505
#define maxm 126000
using namespace std;
struct list
{
int des;
long long weight;
int m;
list() { }
list(int a,long long b,int f)
{
des=a;
weight=b;
m=f;
}
friend bool operator < (struct list c,struct list d)
{
return c.weight>d.weight;
}
};
struct Edge
{
int v;
long long w;
int next;
}edge[250000];
int head[maxn],score[maxn],mark[maxn],cnt,n;
long long dis[maxn];
bool vis[maxn];
void add_edge(int u,int v,long long w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void dijkstra(int s)
{
fill(dis,dis+n,inf);
memset(mark,0,sizeof(mark));
memset(vis,false,sizeof(vis));
priority_queue<struct list> q;
dis[s]=0;
mark[s]=score[s];
q.push(list(s,dis[s],mark[s]));
while(!q.empty())
{
struct list Q=q.top();
q.pop();
if(vis[Q.des])
continue;
vis[Q.des]=true;
for(int i=head[Q.des];i!=-1;i=edge[i].next)
{
int to=edge[i].v;
if(dis[to]>=dis[Q.des]+edge[i].w)
{
if(dis[to]==dis[Q.des]+edge[i].w)
{
if(mark[to]<mark[Q.des]+score[to])
{
mark[to]=mark[Q.des]+score[to];
q.push(list(to,dis[to],mark[to]));
}
}
else
{
mark[to]=mark[Q.des]+score[to];
dis[to]=dis[Q.des]+edge[i].w;
q.push(list(to,dis[to],mark[to]));
}
}
}
}
}
int main()
{
int m,s,e;
scanf("%d%d%d%d",&n,&m,&s,&e);
cnt=0;
memset(head,-1,sizeof(head));
memset(edge,0,sizeof(edge));
memset(score,0,sizeof(score));
for(int i=0;i<n;i++)
scanf("%d",&score[i]);
for(int i=0;i<m;i++)
{
int a,b;
long long t;
scanf("%d%d%lld",&a,&b,&t);
add_edge(a,b,t);
add_edge(b,a,t);
}
dijkstra(s);
printf("%lld %d",dis[e],mark[e]);
return 0;
}