description:

G G G G T GT GT国的国王,他的首都是一张 n n n个点的完全无向图,其中点 i i i和点 j j j之间的无向边长度为 D i s [ i ] [ j ] Dis[i][j] Dis[i][j],恰好点 i i i和点 j j j之间的最短路长度也是 D i s [ i ] [ j ] Dis[i][j] Dis[i][j]

G G G想知道,最少保留多少条道路,可以使点 i i i和点 j j j的最短路长度还是 D i s [ i ] [ j ] Dis[i][j] Dis[i][j]

1 D i s [ i ] [ j ] 1 0 9 1 \le Dis[i][j] \le 10^9 1Dis[i][j]109

n n \leq n
20% 5 5 5
40% 10 10 10
60% 20 20 20
80% 50 50 50
100% 300 300 300

solution:

  • 20 % 20\% 20%

n < = 5 m = n ( n 1 ) / 2 = 10 n <= 5 边数 m = n * (n-1) / 2 = 10 n<=5m=n(n1)/2=10

2 10 o y d 2^{10} 枚举哪⼀一些边被选了了,⽤用floyd验算 210oyd

  • 100 % 100\% 100%

O ( n 3 ) i , j , k n 2 i , j k 使 d i s [ i ] [ k ] + d i s [ k ] [ j ] = d i s [ i ] [ j ] i , j O(n^3)枚举i,j,k ⼀一开始有n^2条边,对于所有i,j,如果存在k 使得dis[i][k]+dis[k][j]=dis[i][j],则i,j之间 的边可以删去 O(n3)i,j,kn2i,jk使dis[i][k]+dis[k][j]=dis[i][j]i,j

code:

#include<cstdio>
using namespace std;
int a[305][305];
int main()
{
	freopen("road.in","r",stdin);
	freopen("road.out","w",stdout); 
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			for(int k=1;k<=n;k++)
			{
				if(a[i][j]==a[i][k]+a[k][j]&&i!=k&&j!=k)
				{
					ans++;
					break;
				}
			}
		}
	}
	printf("%d\n",n*(n-1)/2-ans);
	return 0;
}