Root :: Regionals 2013 :: Africa/Middle East - Arab Contest 6756 - Increasing Shortest Path
给一个图,n个点m条边,q次询问,求从i到j的走过条数不超过c的最短路的长度,走路的时候过的边的长度必须是不减的
数据范围:150点,3000边,1000次询问,时间要求30秒
定义dp[i][j][k]为从i到j,恰好走k次路的最短距离,然后把边排序,逐一添加即可
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct Edge {
int x,y,z;
void read() {
scanf("%d%d%d",&x,&y,&z);
}
friend bool operator < (const Edge &a,const Edge &b) {
return a.z<b.z;
}
};
Edge a[3000];
int dp[151][151][151];
int n,m,q;
inline void update(int &a,int b) {
if (a==-1||a>b) a=b;
}
int main() {
int t,i,x,y,z,j,k;
scanf("%d",&t);
while (t--) {
scanf("%d%d%d",&n,&m,&q);
memset(dp,-1,sizeof(dp));
for (i=1;i<=n;i++) dp[i][i][0]=0;
for (i=0;i<m;i++) {
a[i].read();
}
sort(a,a+m);
for (k=0;k<m;k++) {
x=a[k].x; y=a[k].y; z=a[k].z;
for (i=1;i<=n;i++) {
for (int l=1;l<n;l++)
if (dp[i][x][l-1]!=-1) update(dp[i][y][l],dp[i][x][l-1]+z);
}
}
for (i=0;i<q;i++) {
scanf("%d%d%d",&x,&y,&k);
if (k>=n) k=n-1;
int ans=-1;
for (int l=0;l<=k;l++)
if (dp[x][y][l]!=-1) update(ans,dp[x][y][l]);
printf("%d\n",ans);
}
}
return 0;
}