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

    题目大意:给定一个无向图,求出一条路径,使得边权和加上点权和最小,多组询问

    n<=250 m<=10000

    多组询问,数据范围这么小,很显然就是floyd了,但是这个点权着实让人讨厌哇。。。

    我们重新回想一遍floyd算法的原理:i到j有两种可能:直接到和借助中间接口k,所以取一个min就行了

    我们再往下细细的想一下,k代表的是中间的接口,而且k的枚举顺序是任意的?

    显然是任意的!突破口就在这:我们可以肆意的修改k的枚举顺序!

    所以,这道题就解决了,我们只要从小到大枚举k,跑flyod,点权最大值利用min(c[i],c[j],c[k])来维护就行了!

    正确性?

    当我们枚举到一个k的时候,就代表路径中除了i,j以外没有任何数可能比k大,所以我们在三个中取一个min就行了

    时间复杂度:O(n^3)

    注意处理细节:例如枚举后顺序改变等

    最后,附上本题代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 using namespace std;
     7 //Debug Yufenglin
     8 #define dej printf("Running
    ");
     9 #define dep1(x) cout<<#x<<"="<<x<<endl;
    10 #define dep2(x,y) cout<<#x<<"="<<x<<' '<<#y<<"="<<y<<endl;
    11 #define dep3(x,y,z) cout<<#x<<"="<<x<<' '<<#y<<"="<<y<<' '<<#z<<"="<<z<<endl;
    12 
    13 //Standfor Yufenglin
    14 #define LL long long
    15 #define LB long double
    16 #define reg register
    17 #define il inline
    18 #define inf 1000000000
    19 #define maxn 250
    20 #define maxm 1005
    21 
    22 struct pot
    23 {
    24     int v,id;
    25 };
    26 int n,m,q;
    27 pot c[maxn+5];
    28 int dis[maxn+5][maxn+5],f[maxn+5][maxn+5],pre[maxn+5];
    29 
    30 bool cmp(pot x,pot y)
    31 {
    32     if(x.v==y.v) return x.id<y.id;
    33     return x.v<y.v;
    34 }
    35 int main()
    36 {
    37     scanf("%d%d%d",&n,&m,&q);
    38     for(int i=1;i<=n;i++)
    39     {
    40         scanf("%d",&c[i].v);
    41         c[i].id=i;
    42     }
    43     sort(c+1,c+n+1,cmp);
    44     for(int i=1;i<=n;i++)
    45     {
    46         pre[c[i].id]=i;
    47     }
    48     memset(dis,0x1f,sizeof(dis));
    49     memset(f,0x1f,sizeof(f));
    50     for(int i=1;i<=m;i++)
    51     {
    52         int x,y,z;
    53         scanf("%d%d%d",&x,&y,&z);
    54         dis[pre[x]][pre[y]]=dis[pre[y]][pre[x]]=min(dis[pre[x]][pre[y]],z);
    55     }
    56     for(int i=1;i<=n;i++) dis[i][i]=0;
    57     for(int k=1;k<=n;k++)
    58     {
    59         for(int i=1;i<=n;i++)
    60         {
    61             for(int j=1;j<=n;j++)
    62             {
    63                 if(i==j) continue;
    64                 dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);
    65                 f[i][j]=min(f[i][j],dis[i][j]+max(c[i].v,max(c[j].v,c[k].v)));
    66             }
    67         }
    68     }
    69     for(int i=1;i<=q;i++)
    70     {
    71         int x,y;
    72         scanf("%d%d",&x,&y);
    73         printf("%d
    ",f[pre[x]][pre[y]]);
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    poj 3243 Clever Y(BabyStep GiantStep)
    poj 2417 Discrete Logging
    poj 3481 Double Queue
    hdu 4046 Panda
    hdu 2896 病毒侵袭
    poj 1442 Black Box
    hdu 2815 Mod Tree
    hdu 3065 病毒侵袭持续中
    hdu 1576 A/B
    所有控件
  • 原文地址:https://www.cnblogs.com/yufenglin/p/10702998.html
Copyright © 2011-2022 走看看