N头牛要去参加一场在编号为x(1≤x≤n)的牛的农场举行的派对(1≤N≤1000),有M(1≤m≤100000)条有向道路,每条路长ti(1≤ti≤100);每头牛都必须参加完派对后回到家,每头牛都会选择最短路径,求这n个牛的最短路径(一个来回)中最长的一条的长度。
是最短路的模板题,正反连边,跑两遍最短路,然后选出和最大的(注意反向连边要赋初值)
我用的是DIJ因为图较为稠密,当然SPFA也是可以过的
下面给出代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> using namespace std; inline int min(int a,int b){return a<b?a:b;} inline int max(int a,int b){return a>b?a:b;} inline int rd(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return ; } int n,m,s; int head[100006]; int nxt[200006],to[200006],v[200006]; int total=0; void add(int x,int y,int z){ total++; to[total]=y; v[total]=z; nxt[total]=head[x]; head[x]=total; return ; } struct node{ int u,v; bool operator<(const node x) const{ return u>x.u; } }; priority_queue <node> Q; int dis[100006]; int book[100006]; void dij(int x){ dis[x]=0; node h; h.v=x; h.u=0; Q.push(h); while(!Q.empty()){ h=Q.top(); Q.pop(); if(book[h.v]) continue; book[h.v]=1; for(int e=head[h.v];e;e=nxt[e]){ if(dis[to[e]]>dis[h.v]+v[e]){ dis[to[e]]=dis[h.v]+v[e]; node a; a.v=to[e]; a.u=dis[to[e]]; Q.push(a); } } } return ; } int x[100006]; int y[100006],z[100006]; int dis1[100006]; int main(){ n=rd(),m=rd(),s=rd(); for(int i=1;i<=m;i++){ x[i]=rd(),y[i]=rd(),z[i]=rd(); add(x[i],y[i],z[i]); } memset(dis,127,sizeof(dis)); dij(s); memcpy(dis1,dis,sizeof(dis)); memset(dis,127,sizeof(dis)); memset(head,0,sizeof(head)); memset(book,0,sizeof(book)); total=0; for(int i=1;i<=m;i++) add(y[i],x[i],z[i]); dij(s); int ans=0; for(int i=1;i<=n;i++) ans=max(ans,dis[i]+dis1[i]); write(ans); return 0; }
x(1≤x≤N) 的牛的农场举行的派对。有 M(1≤M≤100000) 条有向道路,每条路长 Ti(1≤Ti≤100);每头牛都必须参加完派对后回到家,每头牛都会选择最短路径。求这 N 头牛的最短路径(一个来回)中最长的一条的长度。 特别提醒:可能有权值不同的重边。