思路:最长路啦~,很明显吧
只需要对dijkstra或者SPFA的模板改一点就即可AC,经典捏~
(os:SPFA本身就可以处理负权值)
1:dijkstra:(底下附上SPFA做法~)
不同点1:用大根堆less哦,以及初始化
for(int i=1; i<=n; i++) dis[i]=-1; //初始化
priority_queue<PII>q;//用less
q.push({1,s});
dis[s]=1.0;
不同点2:大于号替换成小于号,以及这题是乘号
if(dis[j]<dis[t]*w[i]) {
dis[j]=dis[t]*w[i];
q.push({dis[j],j});
}
ACcode:
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<double,int>PII;
const int N=4e7+10;
const int inf=0x3f3f3f3f;
int n,m,e[N],ne[N],h[N],cnt,s,t;
double w[N],dis[N];
bool vis[N];
void add(int u,int v,double ww) {
e[++cnt]=v,w[cnt]=ww,ne[cnt]=h[u],h[u]=cnt;
}
void dijkstra() {
for(int i=1; i<=n; i++) dis[i]=-1; //初始化
priority_queue<PII>q;//用less
q.push({1,s});
dis[s]=1.0;
while(!q.empty()) {
int t=q.top().second;
q.pop();
if(vis[t])continue;
vis[t]=true;
for(int i=h[t]; i; i=ne[i]) {
int j=e[i];
if(dis[j]<dis[t]*w[i]) {
dis[j]=dis[t]*w[i];
q.push({dis[j],j});
}
}
}
}
void solve() {
scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
for(int i=1; i<=m; i++) {
int a,b;
double c;
scanf("%lld%lld%lf",&a,&b,&c);
add(a,b,c);
}
dijkstra();
if(dis[t]==-1)printf("orz\n");
else printf("%.4lf\n",dis[t]);
}
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int tt=1;
// cin>>tt;
while(tt--) solve();
return 0;
}
//3
2:SPFA:(在原有·模板上改动些许)
#include<queue>
#include<cstdio>
using namespace std;
struct Node
{
int head;
double dis;
bool vis;
}node[5005];
struct Edge
{
int to,next;
double len;
}edge[2000005];
int cnt,n,m,s,t;
void addEdge(int u,int v,double w)
{
edge[++cnt].to=v;
edge[cnt].len=w;
edge[cnt].next=node[u].head;
node[u].head=cnt;
}
void SPFA()
{
queue<int>q;
for(int i=1;i<=n;i++)
{
node[i].dis=-0x3f3f3f3f;
node[i].vis=0;
}
node[s].dis=1;
node[s].vis=1;
//初始化要注意
q.push(s);
while(q.size())
{
int u=q.front();
q.pop();
node[u].vis=0;
for(int e=node[u].head;e;e=edge[e].next)
{
int v=edge[e].to;
if(node[v].dis<node[u].dis*edge[e].len)
{
//注意是求最长路,所以是小于号
node[v].dis=node[u].dis*edge[e].len;
//注意这里的计算方法不是加而是乘
if(!node[v].vis)
{
q.push(v);
node[v].vis=1;
}
}
}
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
int u,v;
double w;
scanf("%d%d%lf",&u,&v,&w);
addEdge(u,v,w);
}
SPFA();
if(node[t].dis<=-0x3f3f3f3f)
puts("orz");
else
printf("%.4lf\n",node[t].dis);
//没更新到就说明没路,orz
return 0;
}
over~下班(感谢glgg给俺找的题目,小发发~)