***题意:在x这个点有个聚会,其他的点要到x这个点,然后再会自己原始的点,求一来一回最大的那个距离
做法:两边dijstra算法,因为是单向图,要注意更新顺序***
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<queue> #include<algorithm> using namespace std; #define N 1010 #define INF 0x3f3f3f3f int maps[N][N]; int n, m, x; int dist1[N], dist2[N], vis[N]; void Init() { for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) maps[i][j]=i==j ? 0 : INF; } void dij() { for(int i=1; i<=n; i++) dist1[i]=maps[i][x]; memset(vis, 0, sizeof(vis)); vis[x]=1; for(int i=1; i<=n; i++) { int Min=INF, index=-1; for(int j=1; j<=n; j++) { if(!vis[j]&&dist1[j]<Min) { Min=dist1[j]; index=j; } } if(index==-1) break; vis[index]=1; for(int j=1; j<=n; j++) { if(!vis[j]&&dist1[j]>maps[j][index]+dist1[index]) dist1[j]=maps[j][index]+dist1[index]; } } for(int i=1; i<=n; i++) dist2[i]=maps[x][i]; memset(vis, 0, sizeof(vis)); vis[x]=1; for(int i=1; i<=n; i++) { int Min=INF, index=-1; for(int j=1; j<=n; j++) { if(!vis[j]&&dist2[j]<Min) { Min=dist2[j]; index=j; } } if(index==-1) break; vis[index]=1; for(int j=1; j<=n; j++) { if(!vis[j]&&dist2[j]>dist2[index]+maps[index][j]) dist2[j]=dist2[index]+maps[index][j]; } } } int main() { while(~scanf("%d%d%d", &n, &m, &x)) { Init(); int u, v, len; for(int i=1; i<=m; i++) { scanf("%d%d%d", &u, &v, &len); maps[u][v]=min(len, maps[u][v]); } dij(); int ans=-1; for(int i=1; i<=n; i++) { if(dist1[i]+dist2[i]>ans) ans=dist1[i]+dist2[i]; } printf("%d ", ans); } return 0; }
***两遍spfa,第二次的spfa要使用开始建的反向图,建的反向图也就是以x为如点,dist1里存就是其他店到x的距离***
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<queue> #include<algorithm> using namespace std; #define N 101000 #define INF 0x3f3f3f3f int n, m, x; int dist[N], head[N], dist1[N], head1[N], vis[N], k, k1; struct node { int v, len, next; } a[N], b[N]; void add(int u, int v, int len) { a[k].v=v; a[k].len=len; a[k].next=head[u]; head[u]=k++; } void add1(int u, int v, int len) { b[k1].v=v; b[k1].len=len; b[k1].next=head1[u]; head1[u]=k1++; } int spfa() { queue<int> q; q.push(x); dist[x]=0; vis[x]=1; while(!q.empty()) { int t=q.front(); q.pop(); vis[t]=0; for(int i=head[t]; i!=-1; i=a[i].next) { int v=a[i].v; if(dist[v]>dist[t]+a[i].len) { dist[v]=dist[t]+a[i].len; if(!vis[v]) { vis[v]=1; q.push(v); } } } } memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(x); dist1[x]=0; vis[x]=1; while(!Q.empty()) { int t=Q.front(); Q.pop(); vis[t]=0; for(int i=head1[t]; i!=-1; i=b[i].next) { int v=b[i].v; if(dist1[v]>dist1[t]+b[i].len) { dist1[v]=dist1[t]+b[i].len; if(!vis[v]) { vis[v]=1; Q.push(v); } } } } int ans=-1; for(int i=1; i<=n; i++) { if(ans<dist[i]+dist1[i]&&dist[i]!=INF&&dist1[i]!=INF) ans=dist[i]+dist1[i]; } return ans; } int main() { int u, v, len; while(~scanf("%d%d%d", &n, &m, &x)) { memset(dist, INF, sizeof(dist)); memset(dist1, INF, sizeof(dist1)); memset(head, -1, sizeof(head)); memset(head1, -1, sizeof(head1)); memset(vis, 0, sizeof(vis)); k=k1=1; for(int i=1; i<=m; i++) { scanf("%d%d%d", &u, &v, &len); add(u, v, len); add1(v, u, len); } int ans=spfa(); printf("%d ", ans); } return 0; }