【题目大意】
有$n$个节点和$m$条有向边,经过每条边有一定的时间,求从每个节点走时间最短的路线到编号为$X$的节点再回来(可能是不同的路线因为是有向边),各个节点所需的时间最长为多少。
【思路分析】
是一道dijkstra板子题……然而我真的是基础不牢地动山摇QAQ
用矩阵记录两点之间的距离,先跑一遍dijkstra,然后换一个方向再跑一遍就over啦!详见代码。
【代码实现】
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define g() getchar() 7 #define rg register 8 #define go(i,a,b) for(rg int i=a;i<=b;i++) 9 #define back(i,a,b) for(rg int i=a;i>=b;i--) 10 #define db double 11 #define ll long long 12 #define il inline 13 #define pf printf 14 using namespace std; 15 int fr(){ 16 int w=0,q=1; 17 char ch=g(); 18 while(ch<'0'||ch>'9'){ 19 if(ch=='-') q=-1; 20 ch=g(); 21 } 22 while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g(); 23 return w*q; 24 } 25 const int N=1002; 26 const int INF=1e9+7; 27 int n,m,X,d[N][N],to[N],re[N]; 28 il void work(rg int x){ 29 bool visit[N];//visit记录是否找到最短路 30 int mid=x,minn; 31 memset(visit,0,sizeof(visit)); 32 go(i,1,n) to[i]=d[x][i];//记录从X到各个节点的距离(不是最短的) 33 go(i,1,n-1){ 34 minn=INF; 35 go(j,1,n) 36 if(!visit[j]&&to[j]<minn) minn=to[j],mid=j; 37 //找到当前距离X最近的点 38 visit[mid]=1;//这个点已经找到最短路 39 go(j,1,n) 40 if(!visit[j]) to[j]=min(to[j],to[mid]+d[mid][j]); 41 //以找到的点作为中间点找最短路 42 } 43 return; 44 } 45 int main(){ 46 //freopen("","r",stdin); 47 //freopen("","w",stdout); 48 n=fr();m=fr();X=fr(); 49 go(i,1,n) go(j,1,n) if(i!=j) d[i][j]=INF;//d[i][j]记录从i到j的距离 50 go(i,1,m){ 51 rg int u=fr(),v=fr(),w=fr(); 52 d[u][v]=min(d[u][v],w); 53 } 54 work(X); 55 go(i,1,n) re[i]=to[i]; 56 //re数组记录从X到各个节点的距离,to记录从各个节点到X的距离 57 go(i,1,n) go(j,i+1,n){//矩阵置换,把每条边换个方向 58 rg int mid=d[i][j]; 59 d[i][j]=d[j][i]; 60 d[j][i]=mid; 61 } 62 work(X); 63 rg int ans=0; 64 go(i,1,n) if(i!=X) ans=max(ans,to[i]+re[i]);//找到最长的时间 65 pf("%d ",ans); 66 return 0; 67 }