题目大意:
把floyd改成下面这个样子,还有多少个对点之间的距离是正确的
初学的时候,我也这么写过的
如果点距是正确的,有以下两种情况:
情况一:
两个点之间只有一条边,或 x x x和 y y y是同一个点,或 x x x无法到达 y y y
当然对于前两种,我们需要单独把 x x x和 y y y标记出来,第三种就没有必要了
情况二:
对于其中间点, k k k,能够满足 d [ x ] [ k ] d[x][k] d[x][k]和 d [ k ] [ y ] d[k][y] d[k][y]是正确的,当然这是在情况一正确的基础上实现的
我们可以对每一个点用 d i j k s t r a dijkstra dijkstra进行预处理,再判断情况一,最后再利用情况一求到情况二
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
#define int long long
//#define double long double
#define re int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
const int mod=1e9+7;
const int M=1e8+5;
const int N=1e6+5;//?????????? 4e8
int n,m;
int head[N],tot=1;
int v[N];
struct node
{
int ver,next,edge;
}e[N];
void add(int x,int y,int z)
{
e[++tot].ver=y;
e[tot].edge=z;
e[tot].next=head[x];
head[x]=tot;
}
void dijkstra(int s,int d[])
{
priority_queue < pair < int , int > > q;
for(re i=1;i<=n;i++) v[i]=0;
q.push(mk(0,s));
d[s]=0;
while(q.size())
{
int x=q.top().second;q.pop();
if(v[x]) continue;v[x]=1;
for(re i=head[x];i;i=e[i].next)
{
int y=e[i].ver;
int z=e[i].edge;
if(d[y]>d[x]+z)
{
d[y]=d[x]+z;
q.push(mk(-d[y],y));
}
}
}
}
vector < int > a[3005];
int d[3005][3005],op[3005][3005];
void solve()
{
int ans=0;
cin>>n>>m;
for(re i=0;i<=n+1;i++) for(re j=0;j<=n+1;j++) d[i][j]=1e12;
for(re i=1;i<=m;i++)
{
int x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
}
for(re i=1;i<=n;i++) dijkstra(i,d[i]);
for(re x=1;x<=n;x++) for(re i=head[x];i;i=e[i].next)
{
int y=e[i].ver;
int z=e[i].edge;
if(d[x][y]==z) a[x].pb(y),op[x][y]=1;
}
for(re x=1;x<=n;x++) for(re y=1;y<=n;y++)
{
if(op[x][y]||x==y||d[x][y]==1e12)
{
ans++;
continue;
}
for(auto k:a[x]) if(op[k][y]&&d[x][y]==d[x][k]+d[k][y])
{
ans++;
a[x].pb(y);
op[x][y]=1;
break;
}
}
cout<<ans<<endl;
}
signed main()
{
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
// printf("Case %d:\n",index);
solve();
// puts("");
}
return 0;
}
/*
1
6 5
0 0 0 122 499 8888
*/