Codeforces Round #25 (Div 2 only) C. Roads in Berland

問題概要

n個の都市が双方向に通行可能な道路で結ばれている。
全ての2都市間の最短距離が与えられる。


ここに、k本の道路を新たに作る。
道路を一本作るたびに、全ての二つの都市の組の間の最短距離の和を出力せよ。


n,k≦300を満たす。
かつ、全ての距離は1から1000の整数である。

解法

k回Warshall-Floydを繰り返すと明らかにTLE.
a-bに新たに道路を作ったとき、最短距離の更新され方はi-a-b-jまたはi-b-a-jしかないことに注目すれる。
すると、最短距離の更新はO(n^2)でできるので間に合う。


都市の最短距離の和はlong longを使わなくても大丈夫だと思ってたんだけど、ダメなよう。
n^2は9万で、道の長さは最大1000だから、和は9000万以下のはずなのに。本番はそれではまった。ちょっと理由がわからない。

ソースコード

int n,d[300][300],K;

void run()
{
	cin>>n;
	rep(i,n)rep(j,n)
	{
		cin>>d[i][j];
		d[j][i]=d[i][j];
	}
	cin>>K;
	rep(it,K)
	{
		int a,b,c;
		cin>>a>>b>>c; a--,b--;
		d[a][b]=d[b][a]=min(d[a][b],c);
		
		
		ll sum=0;
		rep(i,n)
		{
			d[i][a]=d[a][i]=min(d[i][a],d[i][b]+c);
			d[i][b]=d[b][i]=min(d[i][b],d[i][b]+c);
		}
		rep(i,n)rep(j,n)d[i][j]=min(d[i][j],min(d[i][a]+c+d[b][j],d[i][b]+c+d[a][j]));
		
		
		rep(i,n)rep(j,i)sum+=d[i][j];
		cout<<sum<<(it==K-1?"\n":" ");
	}
}