第i个点距离1号点的最短路距离记为d(i) 求使得 d(1)<d(2)< ......<d(x)>d(x+1)>.....d(n)的边的构造方案
从左右两边往中间找,若当前点可被之前访问过的点到达的话,就将它的dis值记为之前访问过的最大的dis值加1
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
#define lowbit(x) x&(-x)
using namespace std;
const int N=1e5+10;
long long inf=1e15;
const int MOD=258280327;
int T,n,m,k,x,y,z,l,tot,t,A,B,q;
int cas=1;
int u[N],v[N];
vector<int> vec[N];
bool vis[N];
int dis[N];
int fa[N];
void relax(int x){
for(int i=0;i<vec[x].size();i++){
int v1=vec[x][i];
if(!vis[v1] && !fa[v1]) fa[v1]=x;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aaa","r",stdin);
#endif
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) vec[i].clear();
for(int i=1;i<=n;i++) vis[i]=false,fa[i]=0;
for(int i=1;i<=m;i++){
scanf("%d%d",u+i,v+i);
vec[u[i]].push_back(v[i]);
}
vis[1]=true;
dis[1]=0;
fa[1]=-1;
int now=1;
int pre=2,last=n;
relax(1);
while(pre<=last){
if(fa[pre]){
dis[pre]=now++;
vis[pre]=true;
relax(pre);
pre++;
continue;
}
if(fa[last]){
dis[last]=now++;
vis[last]=true;
relax(last);
last--;
continue;
}
}
for(int i=1;i<=m;i++){
if(fa[v[i]]!=u[i]) printf("%d\n",n);
else printf("%d\n",dis[v[i]]-dis[u[i]]);
}
}
return 0;
}