2 条题解

  • 0
    @ 2025-10-8 17:12:35

    题目求 d[ i ]最小值,所以跑最长路。d[ a ] + x <= d[ b ],从 a 到 b 边权为 x 的边;d[ 0 ]+si <= d[ i ],从 0 到 i 边权为 si 的边;以0为起点跑一遍最长路(若数据有可能没有提到0,则所有点都得进入队列,但只有d[0]=0)。

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    vector<pair<int, int>> G[N]; 
    int d[N];
    bool v[N];
    void spfa()
    {
        queue<int> q;
        memset(d, -0x3f, sizeof(d));
        memset(v,0,sizeof(v));
        q.push(0);d[0]=0;v[0]=1;
        while(!q.empty())
        {
            int x=q.front();q.pop(); v[x]=0;
            for(auto i:G[x])
            {
                int y=i.first, c=i.second;
                if(d[y]<d[x]+c)
                {
                    d[y]=d[x]+c;
                    if(!v[y]) q.push(y),v[y]=1;
                }
            }
        }
    }
    int main()
    {
        int n, m, c;scanf("%d%d%d", &n, &m, &c);
        for(int i=1, si;i<=n;i++)
        {
            scanf("%d", &si);
            G[0].push_back({i, si}); //d[0]+si<=d[i]
        }
        for(int i=1;i<=c;i++)
        {
            int a, b, x;scanf("%d%d%d", &a, &b, &x);
            G[a].push_back({b, x}); //d[a]+x <= d[ b ] 
        }
        spfa();
        for(int i=1;i<=n;i++)printf("%d\n", d[i]);
        return 0;
    }
    
    • 0
      @ 2025-10-8 17:12:21
      /*
      题目求 d[ i ]最小值,所以跑最长路
       d[ a ] + x <= d[ b ]  ,从 a 到 b 边权为 x 的边;
      d[ 0 ]+Si <= d[ i ],从 0 到 i 边权为 Si 的边;
      以0为起点跑一遍最长路(若数据有可能没有提到0,则所有点都得进入队列,但只有d[0]=0)。
      */
      #include<bits/stdc++.h>
      using namespace std;
      const int N=1e5+10;
      vector<pair<int, int>> G[N]; 
      int d[N];
      bool v[N];
      void spfa()
      {
          queue<int> q;
          memset(d, -0x3f, sizeof(d));
          memset(v,0,sizeof(v));
          q.push(0);d[0]=0;v[0]=1;
          while(!q.empty())
          {
              int x=q.front();q.pop(); v[x]=0;
              for(auto i:G[x])
              {
                  int y=i.first, c=i.second;
                  if(d[y]<d[x]+c)
                  {
                      d[y]=d[x]+c;
                      if(!v[y]) q.push(y),v[y]=1;
                  }
              }
          }
      }
      int main()
      {
          int n,m,c;scanf("%d%d%d",&n,&m,&c);
          for(int i=1,si;i<=n;i++)
          {
              scanf("%d", &si);
              G[0].push_back({i,si}); //d[0]+si<=d[i]
          }
          for(int i=1;i<=c;i++)
          {
              int a,b,x;scanf("%d%d%d",&a,&b,&x);
              G[a].push_back({b, x}); //d[a]+x <= d[ b ] 
          }
          spfa();
          for(int i=1;i<=n;i++)printf("%d\n", d[i]);
          return 0;
      }
      • 1

      *【差分约束】[USACO20FEB] Timeline G

      信息

      ID
      6882
      时间
      2000ms
      内存
      256MiB
      难度
      8
      标签
      递交数
      173
      已通过
      21
      上传者