鏈式前向星&&dij堆優化
阿新 • • 發佈:2020-07-17
鏈式前向星
\(next\)指的是上一條同起點邊的位置,\(to\)表示這條邊的終點,\(val\)表示邊權。
\(u、v、val\)分別表示起點,終點,邊權。
\(head[x]\)存以\(x\)為起點的,最後加入的邊的位置\(edge[edge[u]]\)
struct node{ int next,to,val; }edge[maxn]; int head[maxn]; int tot=0; head[x]=-1; void add(int u,int v,int val){ edge[++tot].to=v; edge[tot].val=val; edge[tot].next=head[u]; head[u]=tot; }
dij堆優化
priority_queue<pii,vector<pii >,greater<pii > >qp; int dis[maxn],vis[maxn]; void dijkstra(int src){ for(int i=1;i<=n;++i){ dis[i]=INF; } dis[src]=0; qp.push({0,src}); while(!qp.empty()){ pii t=qp.top;qp.pop(); int u=t.second; if(vis[u])continue; vis[u]=1; for(int i=head[u];i;i=edge[i].next){ if(dis[edge[i].to]>dis[u]+edge[i].val){ dis[edge[i].to]=dis[u]+edge[i].val; qp.push({dis[edge[i].to],edge[i].to}); } } } }
連結:https://ac.nowcoder.com/acm/problem/14550
來源:牛客網
題目描述
小z放假了,準備到RRR城市旅行,其中這個城市有N個旅遊景點。小z時間有限,只能在三個旅行景點進行遊玩。小明租了輛車,司機很善良,說咱不計路程,只要你一次性繳費足夠,我就帶你走遍RRR城。
小z很開心,直接就把錢一次性繳足了。然而小z心機很重,他想選擇的路程儘量長。
然而司機也很聰明,他每次從一個點走到另外一個點的時候都走最短路徑。
你能幫幫小z嗎?
需要保證這三個旅行景點一個作為起點,一個作為中轉點一個作為終點。(一共三個景點,並且需要保證這三個景點不能重複).
輸入描述:
本題包含多組輸入,第一行輸入一個整數t,表示測試資料的組數 每組測試資料第一行輸入兩個數N,M表示RRR城一共有的旅遊景點的數量,以及RRR城中有的路的數量。 接下來M行,每行三個數,a,b,c表示從a景點和b景點之間有一條長為c的路 t<=40 3<=N,M<=1000 1<=a,b<=N 1<=c<=100
輸出描述:
每組資料輸出兩行,
每組資料包含一行,輸出一個數,表示整條路程的路長。
如果找不到可行解,輸出-1.
思路:
遍歷中轉點,找出和中轉點距離最大的兩個地方分別作為起點和終點。
我選擇了鏈式前向星+dij
鏈式前向星遍歷時採用
for(int i=head[u];i;i=edge[i].next){
}
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<" : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<long long,long long> PII;
const int maxn = 2e5 + 10;
int n,m;
int dis[maxn],vis[maxn];
priority_queue<pii,vector<pii >,greater<pii> >qp;
struct edge{
int next;
int to;
int val;
}edge[maxn];
int head[maxn];
int tot=0;
void add(int u,int v,int val){
edge[++tot].to=v;
edge[tot].val=val;
edge[tot].next=head[u];
head[u]=tot;
}
int dij(int src){
while(!qp.empty())qp.pop();
for(int i=1;i<=n;++i){
dis[i]=INF;vis[i]=0;
}
dis[src]=0;
qp.push({0,src});
int x=0,y=0;
while(!qp.empty()){
pii t=qp.top();qp.pop();
int u=t.second;
if(vis[u])continue;
vis[u]=1;
y=max(y,dis[u]);
if(y>x)swap(x,y);
for(int i=head[u];i;i=edge[i].next){
if(vis[edge[i].to])continue;
if(dis[edge[i].to]>dis[u]+edge[i].val){
dis[edge[i].to]=dis[u]+edge[i].val;
qp.push({dis[edge[i].to],edge[i].to});
}
}
}
if(!y)return 0;
else return x+y;
}
int main(){
int t;cin>>t;
while(t--){
cin>>n>>m;
for(int i=1;i<=n;++i)head[i]=-1;
int a,b,c;
while(m--){
cin>>a>>b>>c;
add(a,b,c);add(b,a,c);
}
int ans=-1;
for(int i=1;i<=n;++i){
ans=max(dij(i),ans);
}
if(ans)cout<<ans<<endl;
else cout<<-1<<endl;
}
}