定义一条路径的权值为路径上所有边的编号直接相连所得到的十进制数字的大小
求1到每个点的最短路mod 109+7
n,m≤100000
我思路是拆边,贪心优先走权值最小边来bfs,以此来求最短路径。
代码如下,有没有大佬帮忙看一看:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const LL mod=1e9+7;
const int maxn=6e5+5,maxm=1e5+5;
int n,m,tot,num[15];
bool vis[maxn];
long long dis[maxn];
struct node {
int v,val;
bool operator < (const node t) const {
return val<t.val;
}
};
vector<node>edge[maxn];
void bfs(int s) {
queue<int>q;
q.push(s);
vis[s]=true;
while(!q.empty()) {
int now=q.front();
q.pop();
for(int i=0;i<edge[now].size();i++) {
int v=edge[now][i].v,val=edge[now][i].val;
if(vis[v]) continue;
vis[v]=true;
dis[v]=(dis[now]*10+val)%mod;
q.push(v);
}
}
}
int main() {
scanf("%d%d",&n,&m);
tot=n;
for(int i=1;i<=m;i++) {
int u,v;
scanf("%d%d",&u,&v);
int temp=i,len=0;
while(temp) {
num[++len]=temp%10;
temp/=10;
}
for(int j=tot+len-1,k=tot+1,l=len-1;j-1>tot;j--,k++,l--) {
edge[j].push_back({j-1,num[l]});
edge[k].push_back({k+1,num[l]});
}
if(len>=2) {
edge[u].push_back({tot+1,num[len]}),edge[v].push_back({tot+len-1,num[len]});
edge[tot+1].push_back({u,num[1]}),edge[tot+len-1].push_back({v,num[1]});
}
else edge[u].push_back({v,num[len]}),edge[v].push_back({u,num[len]});
tot=tot+len-1;
}
for(int i=1;i<=tot;i++)
sort(edge[i].begin(),edge[i].end());
/*for(int i=1;i<=tot;i++)
for(int j=0;j<edge[i].size();j++)
cout<<i<<" "<<edge[i][j].v<<" "<<edge[i][j].val<<endl;*/
bfs(1);
for(int i=2;i<=n;i++)
printf("%lld\n",dis[i]);
return 0;
}