题目要求求出n牛头到一点参加聚会然后返回所需的最长时间
其实就是正向建图后求x点到所有点的最短路径以及建立反向图求x到所有点的最短路径,两次最短路径和的最大值就是所求
用Spfa求2次最短路径即可,具体看代码吧
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> using namespace std; const int maxn=100100; const int maxm=1010; int head[2][maxm],pnt[2][maxn],nxt[2][maxn],cost[2][maxn],dist[2][maxm]; int n,m,x,e,ans; bool vis[maxm]; queue<int> q; void AddEdge(int u,int v,int c,int pos) { pnt[pos][e]=v;nxt[pos][e]=head[pos][u];cost[pos][e]=c;head[pos][u]=e++; } void Spfa(int st,int pos) { memset(dist[pos],0x7f,sizeof(dist[pos])); memset(vis,0,sizeof(vis)); q.push(st); dist[pos][st]=0; while(!q.empty()) { int u=q.front(); vis[u]=0; q.pop(); for(int i=head[pos][u];i!=-1;i=nxt[pos][i]) { int v=pnt[pos][i]; if(dist[pos][v]>dist[pos][u]+cost[pos][i]) { dist[pos][v]=dist[pos][u]+cost[pos][i]; if(!vis[v]) { q.push(v); vis[v]=1; } } } } } int main() { while(scanf("%d%d%d",&n,&m,&x)!=EOF) { memset(head,-1,sizeof(head)); ans=e=0; for(int i=0;i<m;i++) { int u,v,c; scanf("%d%d%d",&u,&v,&c); AddEdge(u,v,c,0); AddEdge(v,u,c,1); } Spfa(x,0); Spfa(x,1); for(int i=1;i<=n;i++) ans=max(ans,dist[0][i]+dist[1][i]); printf("%d\n",ans); } return 0; }