1 条题解

  • 0
    @ 2026-6-16 19:38:19

    // 差分约束 SPFA 算法 O(NM)
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=5005,M=5005;
    int idx,h[N],to[M],ww[M],ne[M];
    void add(int a,int b,int c){
      to[++idx]=b,ww[idx]=c,ne[idx]=h[a],h[a]=idx;
    }
    int n,m;
    int d[N],cnt[N];
    bool vis[N];
    
    bool spfa(){
      memset(d,0,sizeof d); //因为求相对距离
      memset(cnt,0,sizeof cnt);
      memset(vis,0,sizeof vis);
      queue<int> q;
      for(int i=1; i<=n; i++) q.push(i),vis[i]=true; //均入队
      while(!q.empty()){
        int u=q.front(); q.pop(); vis[u]=false;
        for(int i=h[u]; i; i=ne[i]){
          int v=to[i];
          if(d[v]>d[u]+ww[i]){ 
            d[v]=d[u]+ww[i]; //最短路
            cnt[v]=cnt[u]+1; //记录走过的边数
            if(cnt[v]==n) return true; //有负环
            if(!vis[v]) q.push(v), vis[v]=true;
          }
        }
      }
      return false; //无负环
    }
    int main(){
      cin>>n>>m;
      for(int i=1,u,v,w; i<=m; i++){
        cin>>u>>v>>w; 
        add(v,u,w);  //u-v<=w
      }
      if(spfa()) cout<<"NO";
      else for(int i=1; i<=n; i++) cout<<d[i]<<' ';
    }
    
    • 1

    信息

    ID
    12494
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    递交数
    7
    已通过
    5
    上传者