在一个有向图中找到,1 - n 的 路径全值和的最小平均值

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define ll long long
int n,d;
int m;
vector<int>ans;
double dis[100005];
int vis[100005];
int pre[100005];
vector<pair<int,double>>adj1[300000];
struct node{
    int u,v,w;
}a[100005];
bool check(double x){
       // pre.assign(n+1);
       // ans.assign(n+1);
       // dis.assign(n+1,1000000000);
	   // pre.assign(n+1,-1);
       // vis.resize(n+1);
       // pre.resize(n+1);
        for(int i = 1;i<=n;i++){
            vis[i] = 0;
            dis[i] = 1e9;
            pre[i] = -1;
            adj1[i].clear();

        }
       for(int i = 1;i<=m;i++){
            adj1[a[i].u].push_back({a[i].v,(a[i].w - x)});
                        
       }
       queue<int>q;
       q.push(1);
       dis[1] = 0;
       vis[1] = 0;
       while(q.size()){
            int y = q.front();
            q.pop();
            vis[y] = 0;
            for(auto e:adj1[y]){
                if(dis[e.first] > dis[y] + e.second){
                    pre[e.first] = y;
                    dis[e.first] = dis[y] + e.second;
                    if(vis[e.first]) continue;
                    q.push(e.first);
                    vis[e.first] = 1;
                }
            }
       }
       if(dis[n]<=0){
            vector<int>c;
            pre[1] = -1;
            int i = n;
            while(pre[i]!=-1){
                c.push_back(i);
                i = pre[i];
            }
            c.push_back(i);
            ans = c;
            return true;
       }
       return false;


}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
	cin >> n >> m;
    for(int i = 1;i <= m;i++){
        int u;
        int v,w;
        cin >> u >> v >> w;
        a[i] = {u,v,w};
    }

    double l=0,r=100;
     for(int i=0;i<100;i++)
     {
         double mid=(l+r)/2;
         if(check(mid)) r=mid;
         else l=mid;
     }
    check(l);
    cout<<ans.size() - 1<<'\n';
    reverse(ans.begin(),ans.end());
    for(int h:ans){
        cout<< h << ' ';
    }



    
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值