NN 个城市,标号从 00 到 N−1N−1,MM 条道路,第 KK 条道路(KK 从 00 开始)的长度为 2K2K,求编号为 00 的城市到其他城市的最短距离。
输入格式
第一行两个正整数 N,MN,M,表示有 NN 个城市,MM 条道路。
接下来 MM 行两个整数,表示相连的两个城市的编号。
输出格式
N−1N−1 行,表示 00 号城市到其他城市的最短路,如果无法到达,输出 −1−1,数值太大的以 mod100000mod100000 的结果输出。
数据范围
2≤N≤1002≤N≤100,
1≤M≤5001≤M≤500
输入样例:
4 4
1 2
2 3
1 3
0 1
输出样例:
8
9
11
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+10,M=5*1e2+10;
typedef long long ll;
int n,m,g[N],ne[M],e[M],w[M],idx,s=100000,inf=0x3f3f3f3f,b,p,q;
bool st[N];
int dist[N];
int pre[N];
typedef pair<int,int> PII;
void add(int a,int b,int c){
e[idx]=b;
w[idx]=c;
ne[idx]=g[a];
g[a]=idx++;
}
void dijkstra(){
priority_queue<PII,vector<PII>,greater<PII> > heap;
memset(dist,inf,sizeof dist);
dist[0]=0;
heap.push({0,0});
while(!heap.empty()){
PII t=heap.top();
heap.pop();
int ver=t.second,distance=t.first;
if(st[ver])
continue;
st[ver]=true;
for(int i=g[ver];i!=-1;i=ne[i]){
int j=e[i];
if(dist[j]>distance+w[i])
dist[j]=distance+w[i];
heap.push({distance+w[i],j});
}
}
}
int qmi(int a,int b,int c){
int res=1;
while(b){
if(b&1)
res=(ll)res*a%c;
a=(ll)a*a%c;
b>>=1;
}
return res;
}
int find(int x){
if(x==pre[x])
return pre[x];
else
return pre[x]=find(pre[x]);
}
int main(){
cin>>n>>m;
memset(g,-1,sizeof g);
for(int i=1;i<n;i++)
pre[i]=i;
for(int i=0;i<m;i++){
int x,y;
scanf("%d %d",&x,&y);
p=find(x);q=find(y);
if(p!=q){
b=qmi(2,i,s);
add(x,y,b);
add(y,x,b);
pre[p]=q;
}
else
continue;
}
dijkstra();
for(int i=1;i<n;i++){
if(dist[i]==inf)
printf("-1\n");
else
printf("%d\n",dist[i]%s);
}
return 0;
}