问题描述
For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race using the T (2 ≤ T ≤ 100) cow trails throughout the pasture.
Each trail connects two different intersections (1 ≤ I1i ≤ 1,000; 1 ≤ I2i ≤ 1,000), each of which is the termination for at least two trails. The cows know the lengthi of each trail (1 ≤ lengthi ≤ 1,000), the two intersections the trail connects, and they know that no two intersections are directly connected by two different trails. The trails form a structure known mathematically as a graph.
To run the relay, the N cows position themselves at various intersections (some intersections might have more than one cow). They must position themselves properly so that they can hand off the baton cow-by-cow and end up at the proper finishing place.
Write a program to help position the cows. Find the shortest path that connects the starting intersection (S) and the ending intersection (E) and traverses exactly N cow trails.
输入格式
* Line 1: Four space-separated integers: N, T, S, and E
* Lines 2..T+1: Line i+1 describes trail i with three space-separated integers: lengthi , I1i , and I2i
输出格式
* Line 1: A single integer that is the shortest distance from intersection S to intersection E that traverses exactly N cow trails.
样例输入
2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9
样例输出
10
题目大意
给出一张无向连通图,求S到E经过k条边的最短路。
解析
倍增Floyd模版题。利用矩阵快速幂的形式可以在\(log\)的时间内处理经过k条路径的最短路。
虽然一共有1000000个点,但是因为只有100条边,可以直接用100条边的端点建图,离散化编号即可。
代码
#include <iostream> #include <cstdio> #define int long long #define N 1000002 using namespace std; const int inf=1<<30; struct Matrix{ int a[500][500]; }S; int n,m,s,t,i,j,id[N],cnt; int read() { char c=getchar(); int w=0; while(c<'0'||c>'9') c=getchar(); while(c<='9'&&c>='0'){ w=w*10+c-'0'; c=getchar(); } return w; } Matrix mult(Matrix a,Matrix b) { Matrix c; for(int i=1;i<=cnt;i++){ for(int j=1;j<=cnt;j++) c.a[i][j]=inf; } for(int k=1;k<=cnt;k++){ for(int i=1;i<=cnt;i++){ for(int j=1;j<=cnt;j++) c.a[i][j]=min(c.a[i][j],a.a[i][k]+b.a[k][j]); } } return c; } Matrix poww(Matrix a,int b) { b--; Matrix ans=a,base=a; while(b){ if(b&1) ans=mult(ans,base); base=mult(base,base); b>>=1; } return ans; } signed main() { n=read();m=read();s=read();t=read(); for(i=1;i<=2*m;i++){ for(j=1;j<=2*m;j++) S.a[i][j]=inf; } for(i=1;i<=m;i++){ int w=read(),u=read(),v=read(); if(!id[u]) id[u]=++cnt; if(!id[v]) id[v]=++cnt; S.a[id[u]][id[v]]=S.a[id[v]][id[u]]=w; } Matrix ans=poww(S,n); cout<<ans.a[id[s]][id[t]]<<endl; return 0; }