“东信杯”广西大学第一届程序设计竞赛(同步赛)H

链接:https://ac.nowcoder.com/acm/contest/283/H
来源:牛客网

题目描述

由于临近广西大学建校90周年校庆,西大开始了喜闻乐见的校园修缮工程!
然后问题出现了,西大内部有许许多多的道路,据统计有N栋楼和M条道路(单向),每条路都有“不整洁度”W,现在校方想知道从S楼到T楼的所有路径中,“不整洁度”乘积最小是多少。
由于答案可能很大,所以你需要将最后的答案109+7取模

输入描述:

第一行为四个整数N、M、S、T,意义如上。
第2至第M+1行每行表示一条道路,有三个整数,分别表示每条道路的起点u,终点v和“不整洁度”W。
输入保证没有自环,可能有重边。
其中W一定是2的整数次幂。

输出描述:

输出一个整数,表示最小的不整洁度之乘积对109+7取模的结果。
若无解请输出 -1
示例1

输入

4 4 1 3
1 2 8
1 3 65536
2 4 2
4 3 16

输出

256
解题思路:
由于每条路的权值可以转化成2的n次幂,所以权值的乘法可以转化成指数的加法,那么这道题就可以求权值指数和的最小值了,这道题就成最短路的问题了。
这里我用了dijkstra求最短路,注意要用优先队列优化。
 
        

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f

typedef long long ll;
const ll mod=1e9+7;
const int maxn=50000+50;
ll dis[maxn];
struct edg{
    int to;
    int w;
};
vector<edg > sm[maxn];
typedef pair<int ,int > P;//最短距离,标点 
void dij(int v){
    fill(dis,dis+maxn,-1);
    priority_queue<P,vector<P>,greater<P> > que;//使用优先队列
    que.push(P(0,v));
    P tem;
    dis[v]=0;
    while(!que.empty()){
        tem=que.top();
        que.pop();
        int i=tem.second;
        if(tem.first>dis[i])
        continue;
        for(int j=0;j<sm[i].size();j++){
            edg e=sm[i][j];
            if(dis[e.to]==-1||dis[e.to]>dis[i]+e.w){
                dis[e.to]=dis[i]+e.w;
                que.push(P(dis[e.to],e.to));
            }
        }
    }
}
int main(){
    int n,m,s,t;
    int u,v;
    ll w;
    ll ans=1;
    edg tem;
    cin>>n>>m>>s>>t;
    for(int i=0;i<m;i++){
        cin>>u>>v>>w;
        w=log(w)/log(2);
        tem.to=v;
        tem.w=w;
        sm[u].push_back(tem);
    }
    dij(s);
    if(dis[t]==-1){
        cout<<"-1"<<endl;
    }
    else{
        ll tem=2;
        while(dis[t]!=0){
            if(dis[t]%2==1){
                ans=(ans*tem)%mod;
            }
            dis[t]/=2;
            tem=(tem*tem)%mod;
        }
        cout<<ans<<endl;
    }
    return 0;
}

 

 



转载于:https://www.cnblogs.com/Zhi-71/p/10022455.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值