T1 银牛派对 luogu 1821
题目大意:
一个有向图
求任意节点到定点的最短距离+定点到该点的最短距离之和的最大值
思路:
正反dij
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 100100 12 #define eps 1e-5 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int ans,n,m,s,dis[MAXN],vis[MAXN],Dis[MAXN],Vis[MAXN]; 22 int to[MAXN],nxt[MAXN],val[MAXN],fst[MAXN],cnt; 23 int To[MAXN],Nxt[MAXN],Val[MAXN],Fst[MAXN],Cnt; 24 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;} 25 void Add(int u,int v,int w) {Nxt[++Cnt]=Fst[u],Fst[u]=Cnt,To[Cnt]=v,Val[Cnt]=w;} 26 struct node 27 { 28 int id,val; 29 bool operator < (const node &a) const 30 { 31 return val>a.val; 32 } 33 }; 34 priority_queue <node> q,Q; 35 void dij() 36 { 37 memset(dis,127,sizeof(dis)); 38 dis[s]=0;q.push((node){s,0});int x; 39 while(!q.empty()) 40 { 41 x=q.top().id;q.pop(); 42 if(vis[x]) continue;vis[x]=1; 43 for(int i=fst[x];i;i=nxt[i]) 44 if(dis[to[i]]>dis[x]+val[i]) {dis[to[i]]=dis[x]+val[i];q.push((node){to[i],dis[to[i]]});} 45 } 46 } 47 void Dij() 48 { 49 memset(Dis,127,sizeof(Dis)); 50 Dis[s]=0;Q.push((node){s,0});int x; 51 while(!Q.empty()) 52 { 53 x=Q.top().id;Q.pop(); 54 if(Vis[x]) continue;Vis[x]=1; 55 for(int i=Fst[x];i;i=Nxt[i]) 56 if(Dis[To[i]]>Dis[x]+Val[i]) {Dis[To[i]]=Dis[x]+Val[i];Q.push((node){To[i],Dis[To[i]]});} 57 } 58 } 59 int main() 60 { 61 n=read(),m=read(),s=read();int a,b,c; 62 while(m--) {a=read(),b=read(),c=read();add(a,b,c);Add(b,a,c);} 63 dij();Dij(); 64 for(int i=1;i<=n;i++) 65 if(i!=s&&dis[i]!=inf&&Dis[i]!=inf) ans=max(ans,dis[i]+Dis[i]); 66 printf("%d",ans); 67 }