由于临近广西大学建校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
把w转化为log(w)后,可以直接累加在反求出指数,最终得到答案
#include<bits/stdc++.h>
#define ll long long
#define maxn 100007
#define inf 0x3f3f3f3f3f3f
using namespace std;
struct node
{
ll to,dis;
node (ll a,ll b){to=a,dis=b;}
friend bool operator <(node a,node b)
{
if(a.dis==b.dis) return a.to<b.to;
return a.dis>b.dis;
}
};
struct edge
{
ll to,dis,next;
}mp[maxn];
ll dis[maxn],vis[maxn],head[maxn];
ll n,m,st,ed,ecnt;
ll mod =1e9+7;
void add(ll a,ll b,ll d)
{
mp[ecnt]={b,d,head[a]};
head[a]=ecnt++;
}
ll qpow(ll a,ll k) {
ll res = 1;
while(k) {
if(k&1) res = (res * a) % mod;
k>>=1;
a = (a*a)%mod;
}
return res % mod;
}
void Dijkstra()
{
for(ll i=0;i<maxn;i++)
dis[i]=inf;
dis[st]=0;
priority_queue<node> que;
que.push(node(st,dis[st]));
while(!que.empty())
{
node x=que.top();
que.pop();
for(ll i=head[x.to];i!=-1;i=mp[i].next)
{
edge y=mp[i];
if(dis[y.to]>x.dis+y.dis)
{
dis[y.to]=x.dis+y.dis;
que.push(node(y.to,dis[y.to]));
}
}
}
if(dis[ed]<inf){
printf("%lld\n",qpow(2,dis[ed]%mod));
}
else printf("-1\n");
}
int main()
{
ll a,b,d;
cin>>n>>m>>st>>ed;
memset(head,-1,sizeof(head));
ecnt=0;
while(m--)
{
cin>>a>>b>>d;
d=log(d*1.000001)/log(2.0);//换底
add(a,b,d);
}
Dijkstra();
return 0;
}