L2-001 紧急救援(最短路变形)

在这里插入图片描述输入样例:
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


错了一个点。

#include <cstdio>
#include <cstring>
#include <queue>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=2000+5,M=300000,INF=(0x3f3f3f3f)<<1;
int head[N],d[N],tot,a[N];
int path[N],cnt[N],num[N],fin[N],vis[N];
int n,m,s,t;
struct Edge{int to,len,nex;}edge[M<<1];
void add(int from,int to,int len)
{
    edge[++tot]=(Edge){to,len,head[from]};head[from]=tot;
}
priority_queue<pair<int,int> >q;
void dijkstra()
{
    m(d,INF);
    cnt[s]=1,num[s]=a[s],d[s]=0,path[s]=-1;
    q.push(make_pair(0,s));
    while(!q.empty())
    {
        int x=q.top().second;q.pop();
        for(int i=head[x];i;i=edge[i].nex)
        {
            int y=edge[i].to,l=edge[i].len;
            if(d[y]==d[x]+l)
            {
                cnt[y]+=cnt[x];
                if(num[x]+a[y]>num[y])
                {
                    num[y]=num[x]+a[y];
                    path[y]=x;
                }
            }
            else if(d[y]>d[x]+l)
            {
                d[y]=d[x]+l;
                cnt[y]=cnt[x],path[y]=x,num[y]=num[x]+a[y];
                q.push(make_pair(-d[y],y));
            }
        }
    }
    printf("%d %d\n",cnt[t],num[t]);
    int tmp=t,fnq=0;
    while(tmp!=-1)
    {
        fin[++fnq]=tmp;
        tmp=path[tmp];
    }
    for(int i=fnq;i>=2;i--)
        printf("%d ",fin[i]-1);
    printf("%d\n",fin[1]-1);
}
int main()
{
    m(path,-1),m(head,0),m(cnt,0),m(num,0);
    tot=1;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    ++s,++t;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    while(m--)
    {
        int from,to,len;
        scanf("%d%d%d",&from,&to,&len);
        ++from,++to;
        add(from,to,len),add(to,from,len);
    }
    dijkstra();
}

猜你喜欢

转载自blog.csdn.net/qq_42576687/article/details/88907532