原题链接:https://www.luogu.org/problem/show?pid=2784
可能,今天是spfa专场?
基本上是一道spfa的裸题,与其他的spfa不同的是,这道题是乘而非加,所以dis[s]要设为1而不是0,否则就全都是0了,而且也不必把dis预处理为无穷大了。
其次还有一点小优化,那就是每个点只被加进队列1次,否则会T掉2个点。
#include<cstdio> #include<algorithm> #include<queue> using namespace std; struct edge { int u,v; double w; }e[2000005]; int head[10005],vis[10005]; double dis[10005]; int n,m,s,t,cnt; void read(int &y) { y=0;char x=getchar(); while(x<'0'||x>'9') x=getchar(); while(x>='0'&&x<='9') { y=y*10+x-'0'; x=getchar(); } } void add(int u,int v,double w) { e[++cnt].u=head[u]; e[cnt].v=v; e[cnt].w=w; head[u]=cnt; } void spfa() { queue<int>q; q.push(s); dis[s]=1;vis[s]=1; while(!q.empty()) { int t=q.front();q.pop(); vis[t]=1; for(register int i=head[t];i;i=e[i].u) { int tmp=e[i].v; if(dis[tmp]<dis[t]*e[i].w) { dis[tmp]=dis[t]*e[i].w; if(vis[tmp]==0) { q.push(tmp); vis[tmp]=1; } } } } } int main() { read(n);read(m);read(s);read(t); for(register int i=1;i<=m;i++) { int u,v;double w; read(u);read(v);scanf("%lf",&w); add(u,v,w); } spfa(); if(dis[t]!=0) printf("%.4lf",dis[t]); else printf("orz"); return 0; }