借鉴了讨论区大佬的最小生成树思路:第n条边的长度比前面所有n-1条边的长度之和还要大,最短路径一定走的是最小生成树
所以遍历第0到第m-1条边,只保存最小生成树的边,其他的扔掉
同时最小生成树内的最短路径都是唯一的,所以边的长度可以直接取模
最后通过DFS计算出0结点到其余节点的路径长度

#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

const int MAX=110;
int father[MAX];
int height[MAX];

struct Edge{
    int to;
    int length;
    Edge(int t,int l):to(t),length(l){}
};

vector<Edge> graph[MAX];

void Initial(int n){
    memset(graph,0,sizeof(graph));
    for(int i=0;i<=n;i++){
        father[i]=i;
        height[i]=0;
    }
}

int Find(int num){
    if(father[num]!=num){
        father[num]=Find(father[num]);
    }
    return father[num];
}

void Union(int x,int y){
    x=Find(x);
    y=Find(y);
    if(x!=y){
        if(height[x]<height[y]){
            father[x]=y;
        }else if(height[x]>height[y]){
            father[y]=x;
        }else{
            father[x]=y;
            height[y]++;
        }
    }
    return;
}

bool visit[MAX];

int DFS(int x,int y){
    visit[x]=true;
    for(int i=0;i<graph[x].size();i++){
        if(visit[graph[x][i].to])
            continue;
        if(graph[x][i].to==y)
            return graph[x][i].length;
        int res=DFS(graph[x][i].to,y);
        if(res!=0)
            return (graph[x][i].length+res)%100000;
    }
    return 0;
}

int main(){
    int n,m;
    cin>>n>>m;
    Initial(n);
    int x,y;
    int multiplyer=1;
    for(int i=0;i<m;i++){
        cin>>x>>y;
        if(Find(x)!=Find(y)){  //只有该边构成最小生成树才将其纳入边集
            graph[x].push_back(Edge(y,multiplyer));
            graph[y].push_back(Edge(x,multiplyer));
            Union(x,y);
        }
        multiplyer=(multiplyer*2)%100000;
    }

    for(int i=1;i<n;i++){
        for(int j=0;j<n;j++)
            visit[j]=false;
        int result=DFS(0,i);  //DFS得到0结点到其他结点的距离
        cout<<result<<endl;
    }
}