Problem 1311 : Test Case Tweaking
問題概要
与えられた重みつき有向グラフにおいて、1番のノードからn番のノードまでの最短路について考える。
グラフの重みをk箇所、好きな非負の値に変えることにより最短路の長さをcにしたい。
このような最小のkを求めよ。
n≦100,辺の本数≦1000,c≦1000000を満たし、かつcは元の最短路の長さよりも小さい。
解法
「k本の重みを変えて最短路をcにできるか」は「k本の重みを0にして最短路をc以下にできるか」に同値である。
これは、各頂点を、「k回辺の重みを0にしてたどり着いたi番目の頂点」と多重化したダイクストラ法により解ける。
ダイクストラ法において、頂点nにたどり着いたときのコストがc以下であれば、(そのような最大の)kが答えになる。
ソースコード
int n,m,C; int d[100][100],e[100][100]; bool v[100]; int main() { while(scanf("%d%d%d",&n,&m,&C),n){ rep(i,n)rep(j,n)e[i][j]=d[i][j]=inf; rep(i,m){ int a,b,c; scanf("%d%d%d",&a,&b,&c); e[a-1][b-1]=c; } d[0][0]=0; rep(i,n){ rep(j,n)v[j]=0; rep(j,n){ int mn=inf,c=0; rep(k,n)if(!v[k]&&d[i][k]<mn)mn=d[i][k],c=k; v[c]=1; if(c==n-1&&mn<=C){ printf("%d\n",i); goto END; } rep(k,n)if(e[c][k]!=inf){ if(!v[k]&&d[i][k]>d[i][c]+e[c][k])d[i][k]=d[i][c]+e[c][k]; if(d[i+1][k]>d[i][c])d[i+1][k]=d[i][c]; } } } END:; } return 0; }