Date:2019/11/6
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191106181030605.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,te xt_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1BobGlGYW4=,size_16,color_FFFFFF,t_70)
→
H
a
p
p
y
B
e
g
i
n
i
n
g
\to Happy\:Begining \!
→HappyBegining
USACO的题
这道题是一个双向的最短路,
这道题只需要跑上两遍Dijkstra就可以
注意建边和清空数组
//Author:PhilFan;
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int cnt,n,m,x,mx = -1000;
int hd[maxn*2],dis[1005],diss[1005];
bool vis[maxn*2];
int st[maxn*2],ed[maxn*2],vl[maxn*2];
struct Node{
int d,id;
Node(){ }
Node(int x,int y):d(x),id(y){}
friend bool operator < (Node a,Node b){
return a.d > b.d;
}
};
priority_queue <Node> q;
struct Edge{
int to,nxt,w;
}edge[maxn*2];
void add(int u, int v,int w){
cnt++;
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].nxt = hd[u];
hd[u] = cnt;
}
void dij(int x){
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof(vis));
dis[x] = 0;q.push(Node(0,x));
while(!q.empty()){
int u = q.top().id; q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int j = hd[u]; j != -1; j = edge[j].nxt){
int v = edge[j].to;
if(dis[u] + edge[j].w < dis[v]){
dis[v] = dis[u] + edge[j].w;
q.push(Node(dis[v],v));//d,id;
}
}
}
}
int main()
{
cnt = 0;
memset(hd,-1,sizeof hd);
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof(vis));
cin>>n>>m>>x;
for(int i = 1; i <= m;i++){
scanf("%d %d %d",&st[i],&ed[i],&vl[i]);
add(st[i],ed[i],vl[i]);
}
//第一遍跑dij
dij(x);
for(int i = 1; i <= n;i++){diss[i] += dis[i];}//数组记录每个点的最小值
cnt = 0;//更新
memset(hd,-1,sizeof hd);
for(int i = 1; i <= m;i++){
add(ed[i],st[i],vl[i]);
}
dij(x);
for(int i = 1; i <= n;i++){
diss[i] += dis[i];
mx = max(mx,diss[i]);
}
cout<<mx<<endl;
return 0;
}
→ H a p p y E n d i n g \to Happy \: Ending →HappyEnding