[最短路,floyd] Codeforces 1204C Anna, Svyatoslav and Maps

题目:http://codeforces.com/contest/1204/problem/C

C. Anna, Svyatoslav and Maps

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

The main characters have been omitted to be short.

You are given a directed unweighted graph without loops with nn vertexes and a path in it (that path is not necessary simple) given by a sequence p1,p2,…,pmp1,p2,…,pm of mm vertexes; for each 1≤i<m1≤i<m there is an arc from pipi to pi+1pi+1.

Define the sequence v1,v2,…,vkv1,v2,…,vk of kk vertexes as good, if vv is a subsequence of pp, v1=p1v1=p1, vk=pmvk=pm, and pp is one of the shortest paths passing through the vertexes v1v1, ……, vkvk in that order.

A sequence aa is a subsequence of a sequence bb if aa can be obtained from bb by deletion of several (possibly, zero or all) elements. It is obvious that the sequence pp is good but your task is to find the shortest good subsequence.

If there are multiple shortest good subsequences, output any of them.

Input

The first line contains a single integer nn (2≤n≤1002≤n≤100) — the number of vertexes in a graph.

The next nn lines define the graph by an adjacency matrix: the jj-th character in the ii-st line is equal to 11 if there is an arc from vertex ii to the vertex jj else it is equal to 00. It is guaranteed that the graph doesn‘t contain loops.

The next line contains a single integer mm (2≤m≤1062≤m≤106) — the number of vertexes in the path.

The next line contains mm integers p1,p2,…,pmp1,p2,…,pm (1≤pi≤n1≤pi≤n) — the sequence of vertexes in the path. It is guaranteed that for any 1≤i<m1≤i<m there is an arc from pipi to pi+1pi+1.

Output

In the first line output a single integer kk (2≤k≤m2≤k≤m) — the length of the shortest good subsequence. In the second line output kk integers v1v1, ……, vkvk (1≤vi≤n1≤vi≤n) — the vertexes in the subsequence. If there are multiple shortest subsequences, print any. Any two consecutive numbers should be distinct.

Examples

input

Copy

4
0110
0010
0001
1000
4
1 2 3 4

output

Copy

3
1 2 4 

input

Copy

4
0110
0010
1001
1000
20
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4

output

Copy

11
1 2 4 2 4 2 4 2 4 2 4 

input

Copy

3
011
101
110
7
1 2 3 1 3 2 1

output

Copy

7
1 2 3 1 3 2 1 

input

Copy

4
0110
0001
0001
1000
3
1 2 4

output

Copy

2
1 4 

Note

Below you can see the graph from the first example:

The given path is passing through vertexes 11, 22, 33, 44. The sequence 1−2−41−2−4 is good because it is the subsequence of the given path, its first and the last elements are equal to the first and the last elements of the given path respectively, and the shortest path passing through vertexes 11, 22 and 44 in that order is 1−2−3−41−2−3−4. Note that subsequences 1−41−4 and 1−3−41−3−4 aren‘t good because in both cases the shortest path passing through the vertexes of these sequences is 1−3−41−3−4.

In the third example, the graph is full so any sequence of vertexes in which any two consecutive elements are distinct defines a path consisting of the same number of vertexes.

In the fourth example, the paths 1−2−41−2−4 and 1−3−41−3−4 are the shortest paths passing through the vertexes 11 and 44.

题意:

给出n个点和他们的邻接关系,再给出一个序列,问如何删去尽可能多的点使得剩下的点的最短路仍是原序列

思路:

如果当前点到当前遍历到的点的距离大于最短路,则说明当前点是必须被加进答案的,因为要保证最短路是给出的序列,如果不选这个点就会让序列最短路变短,
所以更新答案的当前节点为遍历到的节点的上一个节点,当前节点到遍历的点的最短距离也要更新
比如样例1中原序列为1 2 3 4,其中1->2->3距离为2,而1->3的最短路为1,所以我们要加入2节点才能保证最短路仍是原来的序列,否则最短路就会变短

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int amn=1e2+5,amn1=1e6+6,inf=0x3f3f3f3f;
 4 int dis[amn][amn],a[amn][amn],p[amn1],ans[amn1];
 5 int main(){
 6     int n,m;char in;
 7     ios::sync_with_stdio(0);
 8     cin>>n;
 9     for(int i=1;i<=n;i++){
10         for(int j=1;j<=n;j++){
11             cin>>in;
12             a[i][j]=in-‘0‘;
13             if(i==j)dis[i][j]=0;
14             else{
15                 if(a[i][j])dis[i][j]=1;
16                 else dis[i][j]=inf;
17             }
18         }
19     }
20     ///floyd求任意两点间的最短路
21     for(int i=1;i<=n;i++)
22         for(int j=1;j<=n;j++)
23             for(int k=1;k<=n;k++)
24                 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
25     cin>>m;
26     for(int i=1;i<=m;i++)cin>>p[i];
27     int d=0,tp=0;   ///d为当前点到当前遍历到的点的距离
28     ans[++tp]=p[1]; ///题目要求开头必须在序列中
29     for(int i=2;i<=m;i++){
30         d+=dis[p[i-1]][p[i]];
31         if(d<=dis[ans[tp]][p[i]])continue;
32         ans[++tp]=p[i-1];   ///如果当前点到当前遍历到的点的距离大于最短路,则说明当前点是必须被加进答案的,因为要保证最短路是给出的序列,如果不选这个点就会让最短路变短,所以更新答案的当前节点,当前节点到遍历的点的最短距离也要更新
33         d=dis[ans[tp]][p[i]];
34     }
35     ans[++tp]=p[m]; ///题目要求结尾必须在序列中
36     printf("%d\n",tp);
37     for(int i=1;i<=tp;i++)printf("%d%c",ans[i],i<tp?‘ ‘:‘\n‘);
38 }
39 /**
40 给出n个点和他们的邻接关系,再给出一个序列,问如何删去尽可能多的点使得剩下的点的最短路仍是原序列
41 如果当前点到当前遍历到的点的距离大于最短路,则说明当前点是必须被加进答案的,因为要保证最短路是给出的序列,如果不选这个点就会让序列最短路变短,
42 所以更新答案的当前节点为遍历到的节点的上一个节点,当前节点到遍历的点的最短距离也要更新
43 比如样例1中原序列为1 2 3 4,其中1->2->3距离为2,而1->3的最短路为1,所以我们要加入2节点才能保证最短路仍是原来的序列,否则最短路就会变短
44 **/

原文地址:https://www.cnblogs.com/Railgun000/p/11417427.html

时间: 2024-10-11 19:17:01

[最短路,floyd] Codeforces 1204C Anna, Svyatoslav and Maps的相关文章

Codeforces1204C. Anna, Svyatoslav and Maps (贪心 + Floyd)

题目链接:传送门 题目大意: 给出n<=100的有向图,和路径p,求p的最短子序列v,使得依次经过v中所有点的路径为p. 思路: 题意其实就是让我们求路径上的一些关键点v,对于所有的关键点:vi到vi+1的最短路的长度,等于vi到vi+1这两个点在序列p中的下标的差,且vi到vi+2的最短路的长度,小于vi到vi+2在序列p中的下标的差. 如果用dis[u][v] 表示:在题目给出的有向图中,从u出发到v的最短路径的长度.则: 1.p1和pm都是关键点. 2.假设u是之前的最后一个关键点,如果d

CF1204C Anna, Svyatoslav and Maps

题意 在给定的序列P中求一个子序列,使得在图中按照该子序列进行最短路径移动时可以完整经过原序列P code #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #define maxn 105 #define maxm 1000010 #define inf 0x3f3f3f3f using namespace std ; int n ,m , idx

Problem B Codeforces 295B 最短路(floyd)

Description Greg has a weighed directed graph, consisting of n vertices. In this graph any pair of distinct vertices has an edge between them in both directions. Greg loves playing with the graph and now he has invented a new game: The game consists

SDUT 2930-人活着系列之开会(最短路Floyd)

人活着系列之开会 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 人活着如果是为了事业,从打工的到老板的,个个都在拼搏,奋斗了多年终于有了非凡成就,有了一笔丰富的钱财.反过来说,人若赚取了全世界又有什么益处呢?生不带来,死了你还能带去吗?金钱能买保险,但不能买生命,金钱能买药品,但不能买健康,人生在世,还是虚空呀! 在苍茫的大海上,有很多的小岛,每个人都在自己的小岛上.又到了开会的时候了,鹏哥通过飞信告知了每个人,然后大家就开

【bzoj2324】[ZJOI2011]营救皮卡丘 最短路-Floyd+有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend/p/6832504.html 题目描述 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队一共有N个据点,据点之间存在M条双向道路.据点分别从1到N标号.小智一行K人从真新镇出发,营救被困在N号据点的皮卡丘.为了方便起见,我们将真新镇视为0号据点,一开始K个人都在0号点. 由于火箭队的重重布防,要想摧毁K号据点,必须

UVa10048_Audiophobia(最短路/floyd)(小白书图论专题)

解题报告 题意: 求所有路中最大分贝最小的路. 思路: 类似floyd算法的思想,u->v可以有另外一点k,通过u->k->v来走,拿u->k和k->v的最大值和u->v比较,存下最小的值. #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #define inf 0x3f3f3f3f using namespace std;

POJ训练计划2253_Frogger(最短路/floyd)

解题报告 题意: 求0到1所有路中最大值最小的那个数. 思路: floyd. #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #define inf 0x3f3f3f3f using namespace std; int n,m,q; double mmap[210][210]; struct node { double x,y; } p[210]; doub

UVa10099_The Tourist Guide(最短路/floyd)(小白书图论专题)

解题报告 题意: 有一个旅游团现在去出游玩,现在有n个城市,m条路.由于每一条路上面规定了最多能够通过的人数,现在想问这个旅游团人数已知的情况下最少需要运送几趟 思路: 求出发点到终点所有路当中最小值最大的那一条路. 求发可能有多种,最短路的松弛方式改掉是一种,最小生成树的解法也是一种(ps,prime和dijs就是这样子类似的) #include <iostream> #include <cstdio> #include <cstring> #include <

ACM/ICPC 之 最短路-Floyd+SPFA(BFS)+DP(ZOJ1232)

这是一道非常好的题目,融合了很多知识点. ZOJ1232-Adventrue of Super Mario 这一题折磨我挺长时间的,不过最后做出来非常开心啊,哇咔咔咔 题意就不累述了,注释有写,难点在于状态转移方程的确立和SPFA的过程 1 //最短路:Floyd+SPFA(BFS)+DP 2 //Time:20Ms Memory:336K 3 //题目很好,数据较弱,网上部分代码有些问题却能够A掉 4 //题意:超级马里奥要从A+B处背着公主以最短路程到达1处,其中1-A是村庄,剩下的是城堡