P1821 [USACO07FEB]银牛派对Silver Cow Party

P1821 [USACO07FEB]银牛派对Silver Cow Party

最短路Dijkstra

十分显然地,做两遍最短路。

原图跑一遍(出行),反向图跑一遍(归程)。把每个点的2次最短路的结果之和拿来做比较即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue>
using namespace std;
template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
template <typename T> inline void read(T &x){
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
struct data{
    int d,u;
    bool operator < (const data &tmp) const{return d>tmp.d;}
};
int n,m,s,cnt[2],d[2][1002],hd[2][1002],nxt[2][100002],ed[2][100002],poi[2][100002],val[2][100002];
inline void add(int x,int y,int v,int p){
    nxt[p][ed[p][x]]=++cnt[p]; hd[p][x]= hd[p][x] ? hd[p][x]:cnt[p];
    ed[p][x]=cnt[p]; poi[p][cnt[p]]=y; val[p][cnt[p]]=v;
}
void dijkstra(int p){ 
    memset(d[p],127,sizeof(d[p]));
    priority_queue <data> h; h.push((data){d[p][s]=0,s});
    while(!h.empty()){
        data x=h.top(); h.pop();
        if(x.d!=d[p][x.u]) continue;
        for(int i=hd[p][x.u];i;i=nxt[p][i])
            if(d[p][x.u]+val[p][i]<d[p][poi[p][i]]){
                d[p][poi[p][i]]=d[p][x.u]+val[p][i];
                h.push((data){d[p][poi[p][i]],poi[p][i]});
            }
    }
}
int main(){
    read(n); read(m); read(s); int q1,q2,q3;
    for(int i=1;i<=m;++i) read(q1),read(q2),read(q3),add(q1,q2,q3,0),add(q2,q1,q3,1); //建正/反向图
    dijkstra(0); dijkstra(1); int ans=0; //正反图各跑一遍最短路
    for(int i=1;i<=n;++i) ans=max(ans,d[0][i]+d[1][i]); //比较两次权值之和,即为最长的最短路
    printf("%d",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/kafuuchino/p/9682593.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值