TFOJS-1138

来源:互联网 发布:sql 某个字段包含字符 编辑:程序博客网 时间:2024/05/17 06:29

Find the Path

Time Limit:20000MS Memory Limit:32768K

    如果这一题把每个城市的警察的数量这个限制去掉的话,我想每个人都能轻易的做出来,那样的话直接使用Floyd算法求出每个城市之间的最短路便可以了。

    但这个问题的难点就在它要限制在每个城市的警察数量(cops)不超过k的前提下的最短路,一开始没什么思路,一些方法因为有些方面不足也都被摒弃了。这是应该想着去对Floyd加以改动,使之适合这一题,我们都知道Floyd的第一层(for(k=0;k<n;k++))是按照从第1个节点到第N个节点的顺序来更新的,当更新到第k个节点时所得到的最短路径d[i][j]是i到j由前k个结点所组成的最短路径,这时不一定是全局最优的最短路径,但是肯定是由前k个城市组成的最短路径。以此为契机,先把每个城市的cops按照从小到大的顺序排序,Floyd的第一层按照cops从小到大来更新ans[k][i][j],ans[k][i][j]表示前k个结点更新出来的从i到j的最短路径,如果cops[k]是小于等于给定限制的最大的城市里的cops,那么ans[k][i][j]就是query的答案。

    对于每个query,使用upper_bound()函数可以得到第一个刚好小于等于cops[k]的地址,然后减去cops就是下标。在判断下ans[k][i][j]是否是给定的初始无穷大值就知道ans[k][i][j]是否是答案。

#include <iostream>#define MAX_INT 1073741823using namespace std;int n,m,d[202][202];int pos[202],cops[202];int ans[202][202][202];inline bool cmp(int i,int j){  return cops[i]<cops[j]; }void readin(void){     int i,j,u,v,k,query;     cin >> n >> m;     for(i=0;i<n;i++)     {         cin >> cops[i];         pos[i]=i;     }     for(i=0; i<n; i++)       for(j=0; j<n; j++)         if(i==j) d[i][j]=0;         else d[i][j]=MAX_INT;      for(i=0; i<m; i++)     {        cin >> u >> v >> k;        d[u][v]=d[v][u]=k;     }     sort(pos,pos+n,cmp);     for(i=0; i<n; i++)        for(j=0; j<n; j++)           ans[0][i][j] = d[i][j];          for(k=0; k<n; k++)     {        v=pos[k];         for(i=0; i<n; i++)          for(j=0; j<n; j++)          {            ans[k+1][i][j]=ans[k][i][j];            if(ans[k+1][i][j]>ans[k][i][v]+ans[k][v][j])               ans[k+1][i][j]=ans[k][i][v]+ans[k][v][j];          }     }     sort(cops,cops+n);     cin >> query;     while(query--)     {        cin >> u >> v >> k;        i=upper_bound(cops,cops+n,k)-cops;        if(ans[i][u][v]>=MAX_INT) cout << -1 << endl;        else cout << ans[i][u][v] << endl;     }}int main(){    int test;    cin >> test;    while(test--)    {       readin();       if(test) cout << endl;    }    return 0;}

原创粉丝点击