题意:给一个有向图,你可以把边的权值改为非负数,问最少需要改几条边才能让1到n的最短路等于c
图上dp
dp[i][k]:改k条边后,最短的从1到i的最短路
从小到大每个k跑一次spfa,
如果dp[n][k]<=c,k就是答案
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
int n, m, c;
int g[105][105];
int dp[105][1005];
int spfa(int k)
{
for(int i = 0; i <= n; i++)
dp[i][k] = INF;
bool vis[105] = {false};
queue<int> q;
dp[1][k] = 0; q.push(1); vis[1] = true;
while(!q.empty())
{
int p = q.front(); q.pop(); vis[p] = false;
for(int i = 1; i <= n; i++)
{
if(g[p][i] == INF) continue;
int nd = dp[p][k] + g[p][i];
if(k > 0) nd = min(nd, dp[p][k - 1]);
if(dp[i][k] <= nd) continue;
dp[i][k] = nd;
if(!vis[i]) q.push(i), vis[i] = true;
}
}
return dp[n][k];
}
int spfa()
{
for(int k = 0; k <= m; k++)
if(spfa(k) <= c) return k;
}
int main()
{
while(scanf("%d%d%d", &n, &m, &c) && n != 0)
{
for(int i = 0; i <= n; i++)
for(int j = 0; j <= n; j++)
g[i][j] = INF;
for(int i = 0; i < m; i++)
{
int a, b, v;
scanf("%d%d%d", &a, &b, &v);
g[a][b] = v;
}
printf("%d\n", spfa());
}
}