2 条题解

  • 0
    @ 2026-6-17 0:24:34

    // 最短路→最小环 Floyd 算法 O(N^3)
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=110,INF=0x3f3f3f3f;
    int n,m,cnt,res=INF;
    int w[N][N],d[N][N];
    int p[N][N],path[N];
    
    void get_path(int i,int j){ //递归 i,j 之间的点
      if(p[i][j]==0) return;
      int k=p[i][j];
      get_path(i,k);
      path[++cnt]=k;
      get_path(k,j);
    }
    void Floyd(){
      for(int k=1; k<=n; k++){
        for(int i=1;i<k;i++)
        for(int j=i+1;j<k;j++)
        if(res>1ll*d[i][j]+w[i][k]+w[j][k]){
          res=d[i][j]+w[i][k]+w[j][k]; //更新最小环
          cnt=0;
          path[++cnt]=i; path[++cnt]=k; path[++cnt]=j;
          get_path(j,i); //获取j到i的最短路上的中间点
        }
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        if(d[i][j]>d[i][k]+d[k][j]){
          d[i][j]=d[i][k]+d[k][j]; //更新最短路
          p[i][j]=k; //记录从i到j的最短路经过k点
        }
      }  
    }
    int main(){
      cin>>n>>m;
      memset(w,0x3f,sizeof w);
      for(int i=1;i<=n;i++) w[i][i]=0; //去自环
      for(int a,b,c;m--;){
        cin>>a>>b>>c;
        w[a][b]=w[b][a]=min(w[a][b],c); //存边权,去重边
      }
      
      memcpy(d,w,sizeof d);
      Floyd();
      if(res==INF) puts("No solution.");
      else for(int i=1;i<=cnt;i++) cout<<path[i]<<' ';
    }
    
    • 0
      @ 2025-10-8 16:57:03
      #include<bits/stdc++.h>
      using namespace std;
      const int N=110, INF=0x0f0f0f0f;
      int a[N][N], d[N][N], p[N][N];
      vector<int> path;
      void getp(int i, int j)
      {
          if(p[i][j]==0) return ;
          getp(i, p[i][j]); 
          path.push_back(p[i][j]);
          getp(p[i][j], j);
      }
      int main()
      {
          int n, m; scanf("%d%d", &n, &m);
          memset(a,0x0f, sizeof(a)); 
          for(int i=1; i<=m; i++)
          {
              int x, y, c; scanf("%d%d%d", &x, &y, &c);
              a[x][y]=a[y][x]=min(a[x][y], c);
          }
          int ans=INF;
          memset(p, 0, sizeof(p)); 
          memcpy(d, a, sizeof(a)); 
          for(int k=1; k<=n; k++)
          {
              for(int i=1;i<k;i++)
                  for(int j=i+1;j<k; j++) if(d[i][j]+a[i][k]+a[k][j]<ans)
                  {
                      ans=d[i][j]+a[i][k]+a[k][j];
                      path.clear(); 
                      path.push_back(i); 
                      getp(i, j); 
                      path.push_back(j); 
                      path.push_back(k);
                  }
              for(int i=1; i<=n; i++)
                  for(int j=1; j<=n; j++) if(d[i][j]>d[i][k]+d[k][j])
                      {d[i][j]=d[i][k]+d[k][j], p[i][j]=k;}
          }
          if(ans==INF) printf("No solution.\n"); 
          else { for(auto i: path) printf("%d ", i); printf("\n");}
          return 0;
      }
      
      • 1

      D110【模板】【最短路:floyd求最小环】[CEOI 1999] Sightseeing trip

      信息

      ID
      1432
      时间
      1000ms
      内存
      64MiB
      难度
      7
      标签
      递交数
      165
      已通过
      40
      上传者