Educational Codeforces Round 38 (Rated for Div. 2) ----D

D. Buy a Ticket

 

问题转换为对于每一个点x,求出一个点y,使得xy的最短路2倍+在y举办的费用最小。

考虑建一个超级源点,向每一个点连一条费用为其举办所需费用,并且原图中的边权值*2,跑一遍最短路,每一个点到超级源点的最短路即为答案。

卡spfa,请用dijkstra。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 using namespace std;
 4 const int inf=2e5+10;
 5 int n,m;
 6 int tot,fi[inf],to[inf<<2],nxt[inf<<2];
 7 int s;
 8 LL cost[inf<<2];
 9 void link(int x,int y,LL z){
10     to[++tot]=y;nxt[tot]=fi[x];fi[x]=tot;cost[tot]=z;
11 }
12 LL dis[inf];
13 struct dijk{
14     int id;
15     LL val;
16     bool operator < (const dijk &o)const{
17         return val>o.val;
18     }
19 };
20 priority_queue<dijk>S;
21 bool vis[inf];
22 void dijkstra(){
23     memset(dis,0x3f,sizeof(dis));
24     dis[s]=0;
25     S.push((dijk){s,0});
26     while(!S.empty()){
27         dijk u=S.top();
28         S.pop();
29         if(vis[u.id])continue;
30         vis[u.id]=1;
31         for(int i=fi[u.id];i;i=nxt[i]){
32             if(dis[to[i]]>dis[u.id]+cost[i]){
33                 dis[to[i]]=dis[u.id]+cost[i];
34                 S.push((dijk){to[i],dis[to[i]]});
35             }
36         }
37     }
38 }
39 int main()
40 {
41     scanf("%d%d",&n,&m);
42     for(int i=1;i<=m;i++){
43         int x,y;
44         LL z;
45         scanf("%d%d%lld",&x,&y,&z);
46         link(x,y,z<<1);link(y,x,z<<1);
47     }
48     for(int i=1;i<=n;i++){
49         LL z;
50         scanf("%lld",&z);
51         link(s,i,z);
52     }
53     dijkstra();
54     for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
55     puts("");
56     return 0;
57 }
View Code

 

 

真的超级感谢这道题目啊,之前写的dijkstra一直是不对的,以至于我一直对其复杂度怀疑(事实上确实是不对的),甚至觉得他和不优化的dijkstra不像是一种算法了,普通的dijkstra每一个点只会被拿来更新一次,而我之前写的优化后的dijkstra是没有标记数组的,也就是说每一个点可能被访问多次,复杂度就不是nlog+m了。而且之前从来没有因为这个被卡过,这次体会到了。

转载于:https://www.cnblogs.com/hyghb/p/8452797.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值