2261 ] 浪裡個浪(spfa)
阿新 • • 發佈:2019-01-27
TonyY是一個喜歡到處浪的男人,他的夢想是帶著蘭蘭姐姐浪遍天朝的各個角落,不過在此之前,他需要做好規劃。
現在他的手上有一份天朝地圖,上面有n個城市,m條交通路徑,每條交通路徑都是單行道。他已經預先規劃好了一些點作為旅遊的起點和終點,他想選擇其中一個起點和一個終點,並找出從起點到終點的一條路線親身體驗浪的過程。但是他時間有限,所以想選擇耗時最小的,你能告訴他最小的耗時是多少嗎?
Input包含多組測試資料。
輸入第一行包括兩個整數n和m,表示有n個地點,m條可行路徑。點的編號為1 - n。
接下來m行每行包括三個整數i, j, cost,表示從地點i到地點j需要耗時cost。
接下來一行第一個數為S,表示可能的起點數,之後S個數,表示可能的起點。
接下來一行第一個數為E,表示可能的終點數,之後E個數,表示可能的終點。
0<S, E≤n≤100000,0<m≤100000,0<cost≤100。
Output輸出他需要的最短耗時。
Sample Input4 4 1 3 1 1 4 2 2 3 3 2 4 4 2 1 2 2 3 4Sample Output
1
思路:
要確定起點和終點,不用kruskal 用spfa
另外因為起點、終點不確定,所以在所有起點前加一個0節點作為公共起點,在所有終點後加一個n+1節點作為公共終點
然後直接套模板
Code:
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<stack> using namespace std; const int MAXN=2e5+10; const int INF=0x3f3f3f3f; int n,m,f,t,v,tot,ans; int dis[MAXN],vis[MAXN],head[MAXN]; struct edge { int to,w,next; }edge[MAXN]; void build(int u,int v,int w) { edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; } void spfa() { queue <int> q; q.push(0); vis[0]=1; dis[0]=0; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; if(u==n+1) { ans=min(ans,dis[u]); continue; } for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to,w=edge[i].w; if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; if(vis[v]==0) { q.push(v); vis[v]=1; } } } } } int main() { while(~scanf("%d%d",&n,&m)) { int a,x; tot=0; ans=INF; memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++) { scanf("%d%d%d",&f,&t,&v); build(f,t,v); } scanf("%d",&a); for(int i=1;i<=a;i++) { scanf("%d",&x); build(0,x,0); } scanf("%d",&a); for(int i=1;i<=a;i++) { scanf("%d",&x); build(x,n+1,0); } spfa(); printf("%d\n",ans); } return 0; }