题目描述 Description
已给定一个N个点
题目保证,c小于在未进行任何操作之前的原图中1到
输入描述 Input Description
输入文件tweak.in。
第一行三个整数,N,
接下来
输出描述 Output Description
输出文件 tweak.out。
一行一个整数,要进行最少多少次操作才能使得最短路长度变为c。
样例输入 Sample Input
3 3 3
1 2 3
2 3 3
1 3 8
样例输出 Sample Output
1
数据范围及提示 Data Size & Hint
N<=100
M<=1000
0<=c<=100000
0<=wi<=10000
30%数据满足 M<=20
50%数据满足 M<=70
思路
显然每次调整都可以视为是把每条边变为0,最终距离小于等于
设fi,j,k表示i到
最终输出时输出满足f1,n,i<=c的最小的i。
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn=100;
const int inf=0x3f3f3f3f;
int n,m,c,dist[maxn+1][maxn+1];
int f[maxn+1][maxn+1][maxn+1];
int main()
{
memset(dist,63,sizeof dist);
memset(f,63,sizeof f);
scanf("%d%d%d",&n,&m,&c);
for(int i=1; i<=n; i++)
{
dist[i][i]=0;
f[i][i][0]=0;
}
for(int i=1; i<=m; i++)
{
int a,b,v;
scanf("%d%d%d",&a,&b,&v);
dist[a][b]=v;
f[a][b][0]=std::min(f[a][b][0],dist[a][b]);
}
for(int k=1; k<=n; k++)
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
f[i][j][0]=std::min(f[i][j][0],f[i][k][0]+f[k][j][0]);
for(int p=1; p<=n; p++)
{
if(dist[k][j]!=inf)
{
f[i][j][p]=std::min(f[i][j][p],f[i][k][p-1]);
}
f[i][j][p]=std::min(f[i][j][p],f[i][k][p]+f[k][j][0]);
}
}
}
}
for(int i=0; i<=n; i++)
{
if(f[1][n][i]<=c)
{
printf("%d\n",i);
break;
}
}
return 0;
}