CF1209F Koala and Notebook
题目描述
题解
我们将每条边拆成单字符的边,用vector存,然后贪心从0-9 BFS一遍即可
代码
#include<bits/stdc++.h>
#define int long long
#define M 1000000
using namespace std;
vector<int>w[M][10],q[M];
//w[i][j]表示以i为起点,边值为j的边的集合
//q[i]表示走i步后,到达的点的集合
int cnt,n,m,dis[M],vis[M],head,tail;
const int mod=1e9+7;
int read(){
int f=1,re=0;
char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-'){f=-1,ch=getchar();}
for(;isdigit(ch);ch=getchar()) re=(re<<3)+(re<<1)+ch-'0';
return re*f;
}
void add(int x,int y,int z){
while(z>=10){
w[++cnt][z%10].push_back(y);
z/=10,y=cnt;
}w[x][z].push_back(y);
}
signed main(){
cnt=n=read(),m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
add(x,y,i);
add(y,x,i);
}q[++tail].push_back(1),vis[1]=1;
while(head<=tail){
for(int i=0;i<=9;i++){
bool bj=0;
for(int j=0;j<q[head].size();j++)
for(int k=0;k<w[q[head][j]][i].size();k++){
int v=w[q[head][j]][i][k];
if(vis[v]) continue;
vis[v]=bj=1;
dis[v]=(dis[q[head][j]]*10+i)%mod;
q[tail+1].push_back(v);//不能直接++tail
}
if(bj) tail++;
}head++;
}for(int i=2;i<=n;i++) printf("%lld\n",dis[i]);
return 0;
}