[CF416E]President‘s Path
President's Path
题解
看到应该就很容易想到Floyed。
我们可以先通过Floyed求出最短路,对于一个点,如果它在最短路上,则一定可以作为拆分点更新这条路径。
如果暴力枚举所有点与边时会T的,由于对于一个点与它相接的最多只有条边,我们可以考虑从这方面优化。
对于每个点,我们可以先算出它到某个点时需要使用的边,最后枚举拆分点时将它加上即可。
时间复杂度。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 505
typedef long long LL;
typedef unsigned long long uLL;
const int INF=0x3f3f3f3f;
const int mo=1e9+7;
typedef pair<int,LL> pii;
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
x*=f;
}
int n,m,f[MAXN][MAXN],g[MAXN][MAXN],cnt[MAXN],ans[MAXN][MAXN];
signed main(){
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
read(n);read(m);
for(int i=1;i<=n;i++)f[i][i]=0;
for(int i=1;i<=m;i++){
int u,v,w;read(u);read(v);read(w);
f[u][v]=f[v][u]=g[u][v]=g[v][u]=min(f[u][v],w);
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=f[j][i]=min(f[i][k]+f[k][j],f[i][j]);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)cnt[j]=0;
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
if(f[i][k]+g[k][j]==f[i][j])cnt[j]++;
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
if(f[i][k]+f[k][j]==f[i][j])
ans[i][j]+=cnt[k];
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(f[i][j]>INF-1)puts("0");
else printf("%d ",ans[i][j]);
return 0;
}

浙公网安备 33010602011771号