HDU--2363

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2363

分析:最短路+二分。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<string>
  7 #include<queue>
  8 #include<vector>
  9 #define ll long long
 10 #define maxn 105
 11 #define inf 0x7fffffff
 12 using namespace std;
 13 int T,n,m,low,up;
 14 int h[maxn],map[maxn][maxn],h1[maxn];
 15 int d[maxn];
 16 bool vis[maxn];
 17 struct edge
 18 {
 19     int to,len;
 20     edge(int x,int y)
 21     {
 22         to=x;len=y;
 23     }
 24 };
 25 vector<edge>e[maxn];
 26 queue<int>q;
 27 void spfa(const int s)
 28 {
 29     while(!q.empty())q.pop();
 30     for(int i=1;i<=n;i++)
 31     {
 32         d[i]=inf;vis[i]=false;
 33     }
 34     d[s]=0;vis[s]=true;
 35     if(h[s]<low||h[s]>up)return;
 36     q.push(s);
 37     while(!q.empty())
 38     {
 39         int u=q.front();q.pop();
 40         for(int i=0;i<e[u].size();i++)
 41         {
 42             if(h[e[u][i].to]>=low&&h[e[u][i].to]<=up)
 43             {
 44                 int tmp=d[u]+e[u][i].len;
 45                 if(d[e[u][i].to]>tmp)
 46                 {
 47                     d[e[u][i].to]=tmp;
 48                     if(!vis[e[u][i].to])
 49                     {
 50                         vis[e[u][i].to]=true;
 51                         q.push(e[u][i].to);
 52                     }
 53                 }
 54             }
 55         }
 56         vis[u]=false;
 57     }
 58 }
 59 int main()
 60 {
 61     scanf("%d",&T);
 62     while(T--)
 63     {
 64         for(int i=1;i<maxn;i++)e[i].clear();
 65         scanf("%d%d",&n,&m);
 66         for(int i=1;i<=n;i++)
 67         {
 68             scanf("%d",&h[i]);
 69             h1[i]=h[i];
 70         }
 71         sort(h1+1,h1+n+1);
 72         int u,v,len;
 73         for(int i=1;i<=m;i++)
 74         {
 75             scanf("%d%d%d",&u,&v,&len);
 76             e[u].push_back(edge(v,len));
 77             e[v].push_back(edge(u,len));
 78         }
 79         int dif=inf,ans,minlen=inf;
 80         int l=0,r=h1[n]-h1[1];
 81         while(l<=r)
 82         {
 83             int mid=(l+r)>>1;
 84             bool flag=false;
 85             for(int i=1;i<=n;i++)
 86             {
 87                 low=h1[i];
 88                 up=low+mid;
 89                 spfa(1);
 90                 if(d[n]!=inf)
 91                 {
 92                     flag=true;
 93                     ans=d[n];
 94                     break;
 95                 }
 96             }
 97             if(flag)
 98             {
 99                 r=mid-1;
100                 if(dif>mid)
101                 {
102                     dif=mid;
103                     minlen=ans;
104                 }
105                 else if(dif==mid&&ans<minlen)
106                 minlen=ans;
107             }
108             else l=mid+1;
109         }
110         printf("%d %d\n",dif,minlen);
111     }
112     return 0;
113 }
View Code

 

posted @ 2013-08-29 09:51  EtheGreat  阅读(181)  评论(0编辑  收藏  举报