zoukankan      html  css  js  c++  java
  • [LUOGU] P2966 [USACO09DEC]牛收费路径Cow Toll Paths

    暴力的想法是

    [f[i][j]=min{f[i][k]+f[k][j]}\ g[i][j]=f[i][j]+max{val[i],val[j],val[k]} ]

    但是这样并不能保证真的取到路径上的点权最大值,Floyd中的k并没有给我们什么好的性质

    但是Floyd的拓扑序是人定的,只是习惯从1到(n)而已

    因此我们按点权排序,保证点权递增,这个式子就是正确的了

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
      int ret=0,f=1;char c;
      while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
      while(isdigit(c))ret=ret*10+c-'0',c=getchar();
      return ret*f;
    }
    #define space putchar(' ')
    #define nextline putchar('
    ')
    void _(int x){if(!x)return;_(x/10);putchar('0'+x%10);}
    void out(int x){if(!x)putchar('0');_(x);}
    
    const int MAXN = 300;
    
    int f[MAXN][MAXN],g[MAXN][MAXN];
    int val[MAXN],id[MAXN];
    int n,m,q;
    
    inline void upmin(int &x,int y){x=min(x,y);}
    
    bool cmp(int x,int y){
      return val[x]<val[y];
    }
    
    int main(){
      memset(f,0x3f,sizeof(f));
      memset(g,0x3f,sizeof(g));
      n=rd();m=rd();q=rd();
      for(int i=1;i<=n;i++)val[i]=rd();
      int x,y;
      for(int i=1;i<=m;i++){
        x=rd();y=rd();
        f[x][y]=f[y][x]=min(f[x][y],rd());
      }
      for(int i=1;i<=n;i++)id[i]=i,f[i][i]=0;
      sort(id+1,id+1+n,cmp);
      for(int _k=1;_k<=n;_k++){
        int k=id[_k];
        for(int _i=1;_i<=n;_i++){
          int i=id[_i];
          for(int _j=1;_j<=n;_j++){
            int j=id[_j];
            upmin(f[i][j],f[i][k]+f[k][j]);
            upmin(g[i][j],f[i][j]+max(val[k],max(val[i],val[j])));
          }
        }
      }
      for(int i=1;i<=q;i++){
        out(g[rd()][rd()]);
        nextline;
      }
      return 0;
    }
    
    
    未经许可,禁止搬运。
  • 相关阅读:
    通过注册表读取设置字体
    StretchBlt
    PatBlt
    如何用MaskBlt实现两个位图的合并,从而实现背景透明
    输出旋转字体
    用字体开透明窟窿
    输出空心字体
    光滑字体
    画贝塞尔曲线
    一些点运算函数
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9804397.html
Copyright © 2011-2022 走看看