ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

最短路 dij链式向前星优先队列优化

2019-08-31 10:39:58  阅读:283  来源: 互联网

标签:val dij int 短路 电影院 道路 链式 include


暑假集训的休息日到了,本想在学校自习的babilong在ly和sun_of_Ice的蛊惑下,被拉去了MY的电影院玩游戏。MY共有n个区域,包括学校,电影院和n-2个其他区域,其他区域中都是休息站,休息站中没有学校和电影院。并且在MY有m条道路,每条道路连接a,b两个区域且通过此条道路需要付出c的价格(双向道路)。他们决定乘坐鸽鸽专车从学校前往电影院,因为这样虽然咕咕咕咕但经济实惠。优惠政策有2条如下所示:

1.MY的每条道路都可以半价优惠。

2.可以选择给定k条道路中的任意一条道路免费,其他道路原价收费。

因为xx的原因,他们只能选择一条优惠政策,当然也可以不选择。

Input
第一行包括4个整数
n
,
m
,
s
,
e
(
2

n

1000
,
1

m

10000
,
1

s

e

n
)
,分别表示有
n
个区域,
m
条道路,学校所在的区域s,电影院所在的区域e。
接下来
m
行每行3个整数
a

b

c
(
1

a

b

n
,
1

c

1000
)
表示
m
条道路的信息。
接下来一个整数
k
(
0

k

1000
)
,表示有
k
条道路可选择其中的一条免费。
最后
k
行,每行一个整数
x
(
1

x

m
)
表示可以选择第
x
条道路免费。

Output
第一行输出从学校到电影院的最小花费,若不能到达输出-1。
Sample Input
Raw
5 5 1 5
1 2 2
2 3 2
2 4 2
3 5 100
4 5 2
1
4
Sample Output
Raw
3
这个题首先用dij求出半价最短路,然后在让能免费的路全部遍历一次,每次记录,计算,再恢复,求出最小。第一次我都是用for循环直接暴力的,但超时了。我一直认为是在求免费路时没有优化,后来想了一下,每一次都要进行dij,我们就可以优化dij,所以用优先队列优化dij就就可以了。
代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#define me(x,b) memset(x,b,sizeof(x))
#define lowbit(x) x&(-x)
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=1e4+5;
const int maxn1=1e6;
int vis[1005];
int d[1005];
int t[1005];
int head[maxn];
int n,m,x,y;
struct node
{
    int t,next,val;
}e[maxn<<2];
void add(int x,int y,int val, int k)
{
    e[k].t=y;
    e[k].val=val;
    e[k].next=head[x];
    head[x]=k;
}
int dij(int a)
{
    me(vis,0);
    for(int i=0;i<=n;i++)
        d[i]=maxn1;
        d[a]=0;
        queue<int>q;
        q.push(a);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            vis[x]=0;
            for(int i=head[x];~i;i=e[i].next)
            {
                int t=e[i].t;
                int val=e[i].val;
                if(d[t]>d[x]+val)
                {
                    d[t]=d[x]+val;
                    if(vis[t]==0)
                    {
                        q.push(t);
                        vis[t]=1;
                    }
                }
            }
        }
        return d[y];
}
int main()
{
    me(head,-1);
    scanf("%d %d %d %d",&n,&m,&x,&y);
    int a,b,v;
    int c=1;
    while(m--)
    {
        scanf("%d %d %d",&a,&b,&v);
        add(a,b,v,c++);
        add(b,a,v,c++);
    }
    int k;
    scanf("%d",&k);
    for(int i=1;i<=k;i++)
        scanf("%d",&t[i]);
          int s=dij(x);
    if(s==maxn1)
    {
        printf("-1\n");
    }
    else
    {
        s=s/2;
    int x1;
    for(int i=1;i<=k;i++)
    {
        x1=e[t[i]*2-1].val;
        e[t[i]*2-1].val=0;
        e[t[i]*2].val=0;
        int s1=dij(x);
        s=min(s1,s);
        e[t[i]*2-1].val=x1;
        e[t[i]*2].val=x1;
    }
    printf("%d\n",s);
    }
    return 0;
}

标签:val,dij,int,短路,电影院,道路,链式,include
来源: https://blog.csdn.net/weixin_44111723/article/details/100169843

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有