https://codeforces.com/contest/1472/problem/G
一开始ans[i]=d[i]
我们按照离1的距离从大到小枚举点u然后枚举他的出边v,如果d[u]
#include
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,k,cnt,tot,cas;
int a[maxl],ans[maxl],d[maxl];
bool vis[maxl];
char s[maxl];
vector e[maxl],b[maxl];
inline void prework()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
e[i].clear(),b[i].clear();
for(int i=1;i<=m;i++)
{
int u,v;scanf("%d%d",&u,&v);
e[u].push_back(v);
}
for(int i=1;i<=n;i++)
vis[i]=false;
queue q;
q.push(1);d[1]=0;vis[1]=true;
while(!q.empty())
{
int u=q.front();q.pop();b[d[u]].push_back(u);
for(int v:e[u])
if(!vis[v])
{
d[v]=d[u]+1;
q.push(v);vis[v]=true;
}
}
}
inline void mainwork()
{
for(int i=1;i<=n;i++)
ans[i]=d[i];
for(int i=n;i>=0;i--)
for(int u:b[i])
for(int v:e[u])
if(d[v]>d[u])
ans[u]=min(ans[u],ans[v]);
else
ans[u]=min(ans[u],d[v]);
}
inline void print()
{
for(int i=1;i<=n;i++)
printf("%d%c",ans[i]," \n"[i==n]);
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}