P5767 [NOI1997] 最优乘车
考察:最短路+思维
洛谷普及题,本蒟蒻没想出来,我是fw.
思路:
在同一路线上的车站,只要是在当前点后面就可以不耗费到达.由此可以想到一个建图思路:在一条路上的,只要是在当前点后面的,就建立一条权值为w的有向边.很容易想到设w =0.但是这样不同路线就较难处理.由此设w = 1,答案是在建图基础上求1->n的最短路.但是此时最短距离多了在第一条无需换乘的次数.所以最后答案-1.但是需要特判n==1的情况.
1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 #include <string> 5 #include <vector> 6 #include <sstream> 7 using namespace std; 8 const int N = 510,M = 110,S = 50000; 9 int m,n,h[N],idx,dist[N]; 10 string s[N]; 11 bool st[N]; 12 vector<int> node; 13 struct Road{ 14 int fr,to,ne,w; 15 }road[S<<1]; 16 void add(int a,int b,int w) 17 { 18 road[idx].to = b,road[idx].w = w,road[idx].ne = h[a],h[a] = idx++; 19 } 20 void spfa(int p) 21 { 22 memset(dist,0x3f,sizeof dist); 23 dist[p] = 0; 24 queue<int> q; 25 q.push(p); 26 st[p] = 1; 27 while(q.size()) 28 { 29 int u = q.front(); 30 q.pop(); 31 st[u] = 0; 32 for(int i=h[u];i!=-1;i=road[i].ne) 33 { 34 int v = road[i].to; 35 if(dist[v]>dist[u]+road[i].w) 36 { 37 dist[v] = dist[u]+road[i].w; 38 if(!st[v]) q.push(v),st[v] =1; 39 } 40 } 41 } 42 if(dist[n]==0x3f3f3f3f) printf("NO\n"); 43 else printf("%d\n",max(dist[n]-1,0)); 44 } 45 int main() 46 { 47 scanf("%d%d",&m,&n); 48 getchar(); 49 getchar(); 50 memset(h,-1,sizeof h); 51 stringstream ss; 52 for(int i=1;i<=m;i++) 53 { 54 getline(cin,s[i]); 55 ss.clear(); 56 ss.str(s[i]); 57 while(1) 58 { 59 int x; 60 ss>>x; 61 if(ss.fail()) break; 62 node.push_back(x); 63 } 64 for(int i=0;i<node.size();i++) 65 for(int j=i+1;j<node.size();j++) 66 { 67 int u = node[i],v = node[j]; 68 add(u,v,1); 69 } 70 node.clear(); 71 } 72 spfa(1); 73 return 0; 74 }
这里复习下StringStream的用法:
1.ss.str(string) 可以读入字符串.
2.ss>>x 可以输入到x中,ss.fail 用于判断输入是否正确.