1131 Subway Map DFS解法 BFS回溯!

In the big cities, the subway systems always look so complex to the visitors. To give you some sense, the following figure shows the map of Beijing subway. Now you are supposed to help people with your computer skills! Given the starting position of your user, your task is to find the quickest way to his/her destination.

subwaymap.jpg

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤ 100), the number of subway lines. Then N lines follow, with the i-th (i=1,,N) line describes the i-th subway line in the format:

M S[1] S[2] ... S[M]

where M (≤ 100) is the number of stops, and S[i]'s (i=1,,M) are the indices of the stations (the indices are 4-digit numbers from 0000 to 9999) along the line. It is guaranteed that the stations are given in the correct order -- that is, the train travels between S[i] and S[i+1] (i=1,,M1) without any stop.

Note: It is possible to have loops, but not self-loop (no train starts from S and stops at S without passing through another station). Each station interval belongs to a unique subway line. Although the lines may cross each other at some stations (so called "transfer stations"), no station can be the conjunction of more than 5 lines.

After the description of the subway, another positive integer K (≤ 10) is given. Then K lines follow, each gives a query from your user: the two indices as the starting station and the destination, respectively.

The following figure shows the sample map.

samplemap.jpg

Note: It is guaranteed that all the stations are reachable, and all the queries consist of legal station numbers.

Output Specification:

For each query, first print in a line the minimum number of stops. Then you are supposed to show the optimal path in a friendly format as the following:

where Xi's are the line numbers and Si's are the station indices. Note: Besides the starting and ending stations, only the transfer stations shall be printed.

If the quickest path is not unique, output the one with the minimum number of transfers, which is guaranteed to be unique.

思路:

利用DFS寻找最短路

利用linemap来储存两个站点之间的line

 1 #include <iostream>
 2 #include <unordered_map>
 3 #include <vector>
 4 using namespace std;
 5 const int inf = 999999;
 6 const int maxn = 10000;
 7 vector<int> Graph[maxn];
 8 unordered_map<int, int> linemap;
 9 int n,k;
10 int mins=inf, mintran=inf;
11 vector<int> path,tmppath;
12 int vis[maxn];
13 
14 int count_trans(vector<int> tmpp){
15     int cnt=0;
16     int idx=linemap[tmpp[0]*maxn+tmpp[1]];
17     for(int i=1;i<tmpp.size()-1;i++){
18         if(linemap[tmpp[i]*maxn+tmpp[i+1]]!=idx){
19             cnt++;
20             idx=linemap[tmpp[i]*maxn+tmpp[i+1]];
21         }
22     }
23     return cnt;
24 }
25 
26 void dfs(int v, int s2){
27     tmppath.push_back(v);
28     if(v==s2){
29         int cnt_trans=count_trans(tmppath);
30         if(tmppath.size()<mins||(tmppath.size()==mins&&cnt_trans<mintran)){
31             mins=tmppath.size();
32             mintran=cnt_trans;
33             path=tmppath;
34         }        
35         tmppath.pop_back();
36         return;
37     }
38     for(int i=0;i<Graph[v].size();i++){
39         if(!vis[Graph[v][i]]){
40             vis[Graph[v][i]]=1;
41             dfs(Graph[v][i], s2);
42             vis[Graph[v][i]]=0;
43         }
44     }
45     tmppath.pop_back();
46 }
47 
48 int main(int argc, char *argv[]) {
49     fill(vis,vis+maxn,0);
50     
51     scanf("%d",&n);
52     int s1,s2,m;
53     for(int i=1;i<=n;i++){
54         scanf("%d %d",&m,&s1);
55         for(int j=1;j<m;j++){
56             scanf("%d",&s2);
57             Graph[s1].push_back(s2);
58             Graph[s2].push_back(s1);
59             linemap[s1*maxn+s2]=linemap[s2*maxn+s1]=i;
60             s1=s2;
61         }
62     }
63     scanf("%d",&k);
64     for(int i=0;i<k;i++){
65         scanf("%d %d",&s1,&s2);
66         mins=mintran=inf;
67         vis[s1]=1;
68         dfs(s1,s2);
69         vis[s1]=0;
70         printf("%d\n",mins-1);        
71         int idx=linemap[path[0]*maxn+path[1]];
72         int ls=path[0];
73         for(int i=1;i<path.size()-1;i++){
74             if(linemap[path[i]*maxn+path[i+1]]!=idx){
75                 printf("Take Line#%d from %04d to %04d.\n",idx,ls,path[i]);
76                 idx=linemap[path[i]*maxn+path[i+1]];
77                 ls=path[i];
78             }
79         }
80         printf("Take Line#%d from %04d to %04d.\n",idx,ls,s2);
81     }
82 }

 

不好的BFS

另外还有一种BFS的方法,它的优点是,如果两个站点很近,或者很直接,那么需要遍历的路径就很少,可能就一条:如3011→3001,但像是7797→1001这样的,由于它有很多条相近的路,并且在BFS中是已经出队的点,vis【i】设1,而不是在入队时设1,这样会导致一些节点多次入队

samplemap.jpg

  1 #include <iostream>
  2 #include <string>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <queue>
  6 #include <unordered_map>
  7 using namespace std;
  8 const int maxn = 10000;
  9 
 10 int n;
 11 vector<int> Graph[maxn];
 12 unordered_map<int, int> LineMap;
 13 unordered_map<int, vector<int> > pre;
 14 
 15 vector<int> tmpp,path;
 16 vector<int> pa;
 17 int mintrans=999999;
 18 
 19 void dfs(int v,int s1){
 20     tmpp.push_back(v);
 21     if(v==s1){
 22         int trans=0;
 23         vector<int> tpa;
 24         for(int i=tmpp.size()-1;i>=0;i--){
 25             printf("%d.",tmpp[i]);
 26         }
 27         printf("\n");
 28         /*for(int i=tmpp.size()-1;i>1;i--){
 29             if(LineMap[tmpp[i]*maxn+tmpp[i-1]]!=LineMap[tmpp[i-1]*maxn+tmpp[i-2]]){
 30                 trans++;
 31                 tpa.push_back(tmpp[i-1]);
 32                 //printf("*\n");
 33             }
 34         }
 35         if(trans<mintrans){
 36             mintrans=trans;
 37             pa=tpa;
 38             path=tmpp;
 39         }*/
 40         tmpp.pop_back();
 41         return;
 42     }
 43     for(int i=0;i<pre[v].size();i++){
 44         dfs(pre[v][i],s1);
 45     }
 46     tmpp.pop_back();
 47     return;
 48 }
 49 
 50 void BFS(int s1,int s2){
 51     for(unordered_map<int, vector<int> >::iterator it=pre.begin();it!=pre.end();it++){
 52         it->second.clear();
 53     }
 54     int vis[maxn];    fill(vis,vis+maxn,0);
 55     queue<int> q;
 56     int lv=0;
 57     int last=s1 ,llast=s1;
 58     q.push(s1);
 59     vis[s1]=1;
 60     while (q.size()) {
 61         int top=q.front(); q.pop();
 62         vis[top]=1;
 63         printf("top=%d\n",top);
 64         if(top==s2) break;
 65         for(int i=0;i<Graph[top].size();i++){
 66             if(!vis[Graph[top][i]]){
 67                 q.push(Graph[top][i]);            
 68                 pre[Graph[top][i]].push_back(top);
 69                 llast=Graph[top][i];
 70                 printf("%d,",Graph[top][i]);
 71             }
 72         }
 73         printf("\n");
 74     }
 75     printf("\n");
 76     for(int i=0;i<pre[1001].size();i++){
 77         printf("%d ;",pre[1001][i]);
 78     }printf("\n");
 79     dfs(s2,s1);
 80 
 81 }
 82 
 83 int main(){
 84     scanf("%d",&n);
 85     int m;
 86     for(int i=1;i<=n;i++){
 87         scanf("%d",&m);
 88         int s1,s2;
 89         scanf("%d",&s1);
 90         for(int j=1;j<m;j++){
 91             scanf("%d",&s2);
 92             Graph[s1].push_back(s2);
 93             Graph[s2].push_back(s1);
 94             LineMap[s1*maxn+s2]=i;
 95             LineMap[s2*maxn+s1]=i;
 96             s1=s2;
 97         }
 98     }
 99     int k;
100     scanf("%d",&k);
101     int s1,s2;
102     for(int i=0;i<k;i++){
103         scanf("%d %d",&s1,&s2);
104         BFS(s1,s2);
105     }
106 }

 

top=7797
1306,
top=1306
1005,3001,3003,4011,
top=1005
1204,
top=3001
3013,
top=3003
2333,
top=4011
8432,
top=1204
1003,2333,2006,
top=3013
3812,
top=2333
9988,3066,
top=8432
6666,
top=1003
3212,
top=2333
9988,3066,
top=2006
2005,
top=3812
3011,
top=9988

top=3066
3212,
top=6666

top=3212
1001,3008,
top=9988

top=3066

top=2005
2004,
top=3011
3010,
top=3212
1001,3008,
top=1001

3212 ;3212 ;
2333 ;2333 ;
7797.1306.1005.1204.1003.3212.1001.
7797.1306.3003.2333.3066.3212.1001.
7797.1306.1005.1204.2333.3066.3212.1001.
7797.1306.3003.2333.3066.3212.1001.
7797.1306.1005.1204.2333.3066.3212.1001.
7797.1306.1005.1204.1003.3212.1001.
7797.1306.3003.2333.3066.3212.1001.
7797.1306.1005.1204.2333.3066.3212.1001.
7797.1306.3003.2333.3066.3212.1001.
7797.1306.1005.1204.2333.3066.3212.1001.

这些重复都是多次入队的结果,可以看出,太远的路就不会被遍历了,但是会有重复遍历的情况

 

 好的BFS

参考 https://blog.csdn.net/a799581229/article/details/79176455

  1 /*************************
  2 题意:
  3 一个特殊的地铁图
  4 求s到e的最短距离路线
  5 如果距离相同,求换乘次数最少的路线
  6 ************************/
  7 /***********************
  8 解题思路:
  9 由于点可能有10000个,用dijkstr容易超时
 10 而这里的特点是只有100条地铁站,每个点最多5个度
 11 即有很多情况是只有1个选择的情况(笔直向下走)
 12 因此,我们选择使用BFS,能充分利用这个特性。
 13 储存图是要把边也存进去,为了判断是否换乘,我们是利用边的组id去判断的。
 14 入队的是行进状态State
 15     该状态包括当前站,当前线路组id,当前行进距离,和当前换乘距离
 16 然后利用优先队列去做队列
 17 因为结果不唯一,所以我们可以设置一个vis[],已经出队的点,就设置vis=1
 18 接下来这个点不需要再入队。
 19 处理要怎么计算换乘和储存换乘节点即可。
 20 *************************/
 21 /***********************
 22 注意:
 23     优先bfs时,注意vis只在入队时判断,只在出队时去设1
 24 *********************/
 25 #include<iostream>
 26 #include<stdio.h>
 27 #include<string>
 28 #include<vector>
 29 #include<queue>
 30 #include<stdlib.h>
 31 #include<algorithm>
 32 #include<string.h>
 33 #include<stack>
 34 #include<map>
 35 #include<set>
 36 #include<unordered_map>
 37 using namespace std;
 38 #define M 10005
 39 #define INF 0x7ffffff
 40  
 41 vector<int> edg[M];
 42 struct Road{
 43     int s;
 44     int e;
 45     int id;
 46 };
 47 Road road[M];
 48  
 49 struct State{
 50     int dis;
 51     int cnum; //change num
 52     int nowcity;
 53     int nowroad;
 54     vector<int> cv;
 55     vector<int> rv;
 56     bool operator < (const State & a) const{
 57         if(dis > a.dis)
 58             return true;
 59         else if(dis == a.dis)
 60             return cnum > a.cnum;
 61         else return false;
 62     }
 63 };
 64 int vis[M];
 65 void dijk(int start,int end){
 66     int i;
 67     priority_queue<State> q;
 68     memset(vis,0,sizeof(vis));
 69     State sta;
 70     sta.cnum = 0;
 71     sta.nowcity = start;
 72     sta.dis = 0;
 73     sta.nowroad = -1;
 74     q.push(sta);
 75     int city;
 76     Road r;
 77     int e;
 78     State pushs;
 79     while(!q.empty()){
 80         sta = q.top();
 81         q.pop();
 82         city = sta.nowcity;
 83         vis[city] = 1;
 84         if(city == end){
 85             int lastc;
 86             sta.cv.push_back(end);
 87             cout<<sta.dis<<endl;
 88             for(i = 0;i < sta.rv.size();i++){
 89                 printf("Take Line#%d from %04d to %04d.\n",sta.rv[i],sta.cv[i],sta.cv[i+1]);
 90             }
 91             break;
 92         }
 93         for(i = 0;i < edg[city].size();i++){
 94             pushs = sta;
 95             r = road[edg[city][i]];
 96             if(r.s == city)
 97                 e = r.e;
 98             else e = r.s;
 99  
100             if(vis[e])
101                 continue;
102             if(r.id != sta.nowroad){
103                 pushs.cnum++;
104                 pushs.cv.push_back(sta.nowcity); //将变换处的起点放入
105                 pushs.rv.push_back(r.id);
106                 pushs.nowroad = r.id;
107             }
108             pushs.dis++;
109             pushs.nowcity = e;
110             q.push(pushs);
111         }
112     }
113 }
114  
115  
116  
117 int main(){
118     int n, i, m, k;
119     int j,node,lastnode;
120     scanf("%d",&n);
121  
122     j=0;
123     for(i = 1;i <= n;i++){
124         scanf("%d",&k);
125         lastnode = -1;
126         while(k--){
127             scanf("%d",&node);
128             if(lastnode != -1){
129                 edg[lastnode].push_back(j);
130                 edg[node].push_back(j);
131                 road[j].s = lastnode;
132                 road[j].e = node;
133                 road[j].id = i;
134                 j++;
135             }
136             lastnode = node;
137         }
138     }    
139     cin>>k;
140     int s, e;
141     while(k--){
142         cin>>s>>e;
143         dijk(s,e);
144     }
145  
146     return 0;
147 }

 

转载于:https://www.cnblogs.com/lokwongho/p/10031533.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值