题意:
就是给你一个图,然后每次你走过一个边,其余的边都变成f(x)=1/(1-x)。问你从1到n的最短路。然后如果是负边权那么就设置成fabs,就是绝对值之和最小的那个最短路。
思考:
看完我感觉这咋做啊,那么复杂,其实这种函数,你连动手化简化简都不化简。其实化简之后发现就有三种状态,所以就是建立分层图就可以了。跑一遍distra。
代码:
int T,n,m,k;
int va[N];
int vis[N];
db dist[N];
vector<pair<int,db> > e[N];
void distra()
{
for(int i=1;i<=3*n;i++) dist[i] = inf;
priority_queue<PII,vector<PII>,greater<PII> > q;
q.push({0,1});
dist[1] = 0;
while(q.size())
{
auto t = q.top();
q.pop();
int now = t.se;
db dis = t.fi;
if(vis[now]) continue;
vis[now] = 1;
for(auto tt:e[now])
{
int spot = tt.fi;
db w = tt.se;
if(dist[spot]>dis+w)
{
dist[spot] = dis+w;
q.push({dist[spot],spot});
}
}
}
}
signed main()
{
IOS;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
db c;
cin>>a>>b>>c;
e[a].pb({b+n,c});
e[b].pb({a+n,c});
c = 1.0/(1-c);
e[a+n].pb({b+2*n,fabs(c)});
e[b+n].pb({a+2*n,fabs(c)});
c = 1.0/(1-c);
e[a+2*n].pb({b,fabs(c)});
e[b+2*n].pb({a,fabs(c)});
}
distra();
db minn = inf;
for(int i=1;i<=3;i++)
minn = min(minn,dist[i*n]);
if(minn==inf) printf("-1\n");
else printf("%.3lf",minn);
return 0;
}
总结:
多多思考呀,积累积累经验。