- 比较懒,不想写大数处理(Dijkstra+大数计算)
- 借鉴MST的思想,MST+DFS即可
- 因为本题MST确定之后,最短路径也是唯一确定的
#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<climits>
using namespace std;
const int maxn=501;
const int INF=INT_MAX;
int father[maxn];//并查集
int height[maxn];
void Initial(int n){
for(int i=0;i<n;i++){
father[i]=i;
height[i]=1;
}
}
int Find(int x){
if(x!=father[x]){
father[x]=Find(father[x]);
}
return father[x];
}
void Union(int x,int y){
int a=Find(x);
int b=Find(y);
if(a==b)return;
else if(height[a]>height[b])father[b]=a;
else if(height[a]<height[b])father[a]=b;
else{
father[b]=a;
height[a]++;
}
}//
struct Edge{
int to;
int distance;
Edge(int t,int d):to(t),distance(d){}
Edge(){}
};
vector<Edge>graph[maxn];//图的邻接矩阵
int dis[maxn];
bool visit[maxn];
void dfs(int x,int cur){//DFS统计路径长度(访问结点、当前长度)
visit[x]=true;
for(int i=0;i<graph[x].size();i++){
int next=graph[x][i].to;//下一结点
int d=graph[x][i].distance;
if(visit[next])continue;
else{
dfs(next,(cur+d)%100000);//递归
dis[next]=(cur+d)%100000;
}
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0)break;
Initial(n);//并查集初始化
int d=1;
for(int i=0;i<m;i++){
int from,to;
scanf("%d%d",&from,&to);
if(Find(from)!=Find(to)){//不在同一集合的点,添加边
Union(from,to);
graph[from].push_back(Edge(to,d));//无向边
graph[to].push_back(Edge(from,d));
}
d=d*2;
d=d%100000;//更新边长
}
fill(dis,dis+n,INF);
dis[0]=0;
fill(visit,visit+n,false);
dfs(0,0);
for(int i=1;i<n;i++){
if(dis[i]==INF)printf("-1\n");
else printf("%d\n",dis[i]);
}
}
return 0;
}