给定
模板题,最短路生成树。
以
大概的证明可以感性理解一下,当我们用点
xxxxxxxxxx82123
45678910
11using namespace std;12
13mt19937 rnd(random_device{}());14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}15bool rnddd(int x){return rndd(1, 100) <= x;}16
17typedef unsigned int uint;18typedef unsigned long long unll;19typedef long long ll;20typedef long double ld;21
22template < typename T = int >23inline T read(void);24
25struct Edge{26 Edge* nxt;27 int to;28 int val;29 int idx;30 OPNEW;31}ed[410000];32ROPNEW(ed);33Edge* head[210000];34
35int N, M;36ll dis[210000];37bool vis[210000];38int idx[210000];39
40void Dijk(void){41 memset(dis, 0x3f, sizeof dis);42 priority_queue < pair < ll, int >, vector < pair < ll, int> >, greater < pair < ll, int > > > cur;43 dis[1] = 0, cur.push({dis[1], 1});44 while(!cur.empty()){45 int tp = cur.top().second; cur.pop();46 if(vis[tp])continue;47 vis[tp] = true;48 for(auto i = head[tp]; i; i = i->nxt)49 if(dis[tp] + i->val < dis[SON])50 dis[SON] = dis[tp] + i->val, idx[SON] = i->idx, cur.push({dis[SON], SON});51 }52}53
54int main(){55 // freopen("random_01.txt", "r", stdin);56 // freopen("out.txt", "w", stdout);57 N = read(), M = read();58 for(int i = 1; i <= M; ++i){59 int s = read(), t = read(), v = read();60 head[s] = new Edge{head[s], t, v, i};61 head[t] = new Edge{head[t], s, v, i};62 }Dijk();63 for(int i = 2; i <= N; ++i)printf("%d%c", idx[i], i == N ? '\n' : ' ');64 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);65 return 0;66}67
68template < typename T >69inline T read(void){70 T ret(0);71 int flag(1);72 char c = getchar();73 while(c != '-' && !isdigit(c))c = getchar();74 if(c == '-')flag = -1, c = getchar();75 while(isdigit(c)){76 ret *= 10;77 ret += int(c - '0');78 c = getchar();79 }80 ret *= flag;81 return ret;82}update-2022_12_03 初稿