Codeforces Round #581 (div. 2) Tutorial C(floyed最短路记录关键节点)

floyed最短路记录关键节点

比赛的时候想到最短路了,但是不知道怎么处理。

后来看了题解,因为以一个点一定要,所以记录第一个节点

对于第二个要不要呢,实际上是取决于第三个点的,如果求出的最短路a1—>a3是小于(3-1)的,如果不记录第二个节点,那么第二个节点就会被抛弃,所以第二个节点记录

如果a1—>a3等于(3-1)的,那么一定可以走1—>2—>3这条路到达3。2就一定不用记录

接下来依次类推,如果某个节点记录了,那么就让他发挥一开始a1的作用。最后别忘了把am放进去。那么就是所求路径了。

感觉有点贪心的意思。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=100+5;
 5 const int inf=9999999;
 6 int mp[maxn][maxn];
 7 int b[1000005];
 8 int n;
 9 int main(){
10     cin>>n;
11     for(int i=1;i<=n;i++){
12         string str;cin>>str;
13         for(int j=0;j<str.size();j++) 
14         {
15             mp[i][j+1]=str[j]-'0';
16             if(mp[i][j+1]==0) mp[i][j+1]=inf;
17             if(i==j+1) mp[i][j+1]=0;
18         }
19     }
20     /*    for(int i=1;i<=n;i++){
21 
22             {
23                     for(int j=1;j<=n;j++)
24                         cout <<mp[i][j]<<" ";
25             }
26             cout <<endl;
27     }*/
28     for(int k=1;k<=n;k++){
29         for(int i=1;i<=n;i++)
30             for(int j=1;j<=n;j++)
31                 mp[i][j]=min(mp[i][k]+mp[k][j],mp[i][j]);
32     }
33     /*    for(int i=1;i<=n;i++){
34 
35             {
36                     for(int j=1;j<=n;j++)
37                         cout <<mp[i][j]<<" ";
38             }
39             cout <<endl;
40     }*/
41     int m;cin>>m;
42     for(int i=1;i<=m;i++) cin>>b[i];
43     vector <int>V;
44     V.push_back(b[1]);
45     int now=b[1];int dis=1;
46     for(int i=3;i<=m;i++)
47     {
48         dis++;
49         if(dis>mp[now][b[i]])
50         {
51             V.push_back(b[i-1]);
52             now=b[i-1];
53             dis=1;
54         }
55     }
56     V.push_back(b[m]);
57     cout <<V.size()<<"\n";
58     for(int i=0;i<V.size();i++) cout <<V[i]<<" ";
59     cout <<"\n";
60     
61     
62     
63     
64     
65     return 0;
66 }

 

posted @ 2019-08-28 14:50  Chuhanjing  阅读(173)  评论(0编辑  收藏  举报