【PAT甲级】1030 Travel Plan (30 分)(SPFA,DFS)
题意:
输入N,M,S,D(N,M<=500,0<S,D<N),接下来M行输入一条边的起点,终点,通过时间和通过花费。求花费最小的最短路,输入这条路径包含起点终点,通过时间和通过花费。
trick:
找了半小时bug终于发现是给dis数组赋初值时范围是1~N,这道题点是从0~N-1的,故初次只通过了第0组数据,初始化改一下边界即可AC。
AAAAAccepted code:
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 int n,m,s,d; 5 int a[507]; 6 typedef struct road{ 7 int x,y,z; 8 }; 9 vector<road>edg[507]; 10 vector<pair<int,int> >pre[507]; 11 vector<pair<int,int> >tmp_path,path; 12 int dis[507]; 13 bool vis[507]; 14 int ans=1e9; 15 void spfa(){ 16 for(int i=0;i<n;++i) 17 dis[i]=1e9; 18 dis[s]=0; 19 vis[s]=1; 20 queue<int>q; 21 q.push(s); 22 while(!q.empty()){ 23 int x=q.front(); 24 vis[x]=0; 25 q.pop(); 26 for(int i=0;i<edg[x].size();++i){ 27 int v=edg[x][i].x; 28 int w=edg[x][i].y; 29 int val=edg[x][i].z; 30 if(dis[v]>dis[x]+w){ 31 dis[v]=dis[x]+w; 32 pre[v].clear(); 33 pre[v].push_back({x,a[val]}); 34 if(!vis[v]){ 35 vis[v]=1; 36 q.push(v); 37 } 38 } 39 else if(dis[v]==dis[x]+w) 40 pre[v].push_back({x,a[val]}); 41 } 42 } 43 } 44 void dfs(int x,int y){ 45 if(x==s) 46 if(y<ans){ 47 ans=y; 48 path=tmp_path; 49 } 50 tmp_path.push_back({x,y}); 51 for(int i=0;i<pre[x].size();++i) 52 dfs(pre[x][i].first,y+pre[x][i].second); 53 tmp_path.pop_back(); 54 } 55 int main(){ 56 cin>>n>>m>>s>>d; 57 int u,v,w; 58 for(int i=1;i<=m;++i){ 59 cin>>u>>v>>w>>a[i]; 60 edg[u].push_back({v,w,i}); 61 edg[v].push_back({u,w,i}); 62 } 63 spfa(); 64 dfs(d,0); 65 cout<<s<<" "; 66 for(int i=path.size()-1;i>=0;--i) 67 cout<<path[i].first<<" "; 68 cout<<dis[d]<<" "<<ans; 69 return 0; 70 }
保持热爱 不懈努力
不试试看怎么知道会失败呢(划掉)
世上无难事 只要肯放弃(划掉)