P1613
跑路
其实还是蛮有思维含量的。
首先明确题意:让我们求所有
这仍然是一个让我们求最优路径的问题,那么我们先转化一下题目基础,让这个题变得比较可做。
首先,我们直接按照路径长度来做肯定是不好做的,发现对答案的贡献单位是每一个长度为
所以说,可以定义一个邻接矩阵
然后我们可以知道,所有
时间复杂度
做法不难,但是真的很有趣。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const ll N=1e2;
ll n,m,u,v;
ll path[N+5][N+5][N+5],dis[N+5][N+5];
inline ll read() {
ll ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9') {ret=(ret<<3)+(ret<<1)+ch-'0';ch=getchar();}
return ret*f;
}
void write(ll x) {
if(x<0) {x=-x;putchar('-');}
ll y=10,len=1;
while(y<=x) {y*=10;len++;}
while(len--) {y/=10;putchar(x/y+48);x%=y;}
}
int main() {
n=read();m=read();
for(ll i=1;i<=m;i++) {
u=read();v=read();
path[u][v][0]=1;
}
for(ll p=1;p<=64;p++) {
for(ll k=1;k<=n;k++) {
for(ll i=1;i<=n;i++) {
for(ll j=1;j<=n;j++) {
path[i][j][p]=path[i][j][p]||
(path[i][k][p-1]&&path[k][j][p-1]);
}
}
}
}
memset(dis,0x3f,sizeof(dis));
for(ll i=1;i<=n;i++) {
for(ll j=1;j<=n;j++) {
for(ll k=0;k<=64;k++) {
if(path[i][j][k]) {
dis[i][j]=1;break;
}
}
}
}
for(ll k=1;k<=n;k++) {
for(ll i=1;i<=n;i++) {
for(ll j=1;j<=n;j++) {
if(dis[i][j]>dis[i][k]+dis[k][j]) {
dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
}
write(dis[1][n]);
return 0;
}