Emergency(山东省第一届ACM程序设计真题+Floyd算法变型)

题目描述

Kudo’s real name is not Kudo. Her name is Kudryavka Anatolyevna Strugatskia, and Kudo is only her nickname.

Now, she is facing an emergency in her hometown:

Her mother is developing a new kind of spacecraft. This plan costs enormous energy but finally failed. What’s more, because of the failed project,

the government doesn’t have enough resource take measure to the rising sea levels caused by global warming, lead to an island flooded by the sea.

Dissatisfied with her mother’s spacecraft and the government, civil war has broken out.

The foe wants to arrest the spacecraft project’s participants and the “Chief criminal” – Kudo’s mother – Doctor T’s family.

At the beginning of the war, all the cities are occupied by the foe. But as time goes by, the cities recaptured one by one.

To prevent from the foe’s arrest and boost morale, Kudo and some other people have to distract from a city to another. Although they can use some other means to transport,

the most convenient way is using the inter-city roads. Assuming the city as a node and an inter-city road as an edge, you can treat the map as a weighted directed multigraph. An inter-city road is available if both its endpoint is recaptured.

Here comes the problem.

Given the traffic map, and the recaptured situation, can you tell Kudo what’s the shortest path from one city to another only passing the recaptured cities?

输入

The input consists of several test cases.

The first line of input in each test case contains three integers N (0<N≤300), M (0<M≤100000) and Q (0<Q≤100000), which represents the number of cities, the numbers of inter-city roads and the number of operations.

Each of the next M lines contains three integer x, y and z, represents there is an inter-city road starts from x, end up with y and the length is z. You can assume that 0<z≤10000.

Each of the next Q lines contains the operations with the following format:

a) 0 x – means city x has just been recaptured.

b) 1 x y – means asking the shortest path from x to y only passing the recaptured cities.

The last case is followed by a line containing three zeros.

输出

For each case, print the case number (1, 2 …) first.

For each operation 0, if city x is already recaptured (that is,the same 0 x operation appears again), print “City x is already recaptured.”

For each operation 1, if city x or y is not recaptured yet, print “City x or y is not available.” otherwise if Kudo can go from city x to city y only passing the recaptured cities,

print the shortest path’s length; otherwise print “No such path.”

Your output format should imitate the sample output. Print a blank line after each test case.

样例输入

3 3 6
0 1 1
1 2 1
0 2 3
1 0 2
0 0
0 2
1 0 2
1 2 0
0 2

0 0 0

样例输出

Case 1:
City 0 or 2 is not available.
3
No such path.
City 2 is already recaptured.
 1 /*
 2 问题
 3 输入顶点数n,路径数m和操作次数q
 4 如果操作数是0,x如果没有被收回时,输出City %d is already recaptured.
 5 如果操作数是1,x和y如果有一个没有被收回,输出City x or y is not available.
 6 如果存在最短路径输出最短路径,不存在路径输出No such path.
 7
 8 解题思路
 9 由于询问次数可能很多和可能重复而且是任意两点间的最短路,所以每次加入一个点时进行一次Floyd,输出相应的结果即可。
10 */
11 #include<cstdio>
12 #include<cstring>
13 const int INF=99999999;
14 int n,m,q;
15 int e[500][500],book[500];
16 void floyd(int x){
17     int i,j;
18     for(i=0;i<n;i++){
19         for(j=0;j<n;j++){
20             if(e[i][j] > e[i][x] + e[x][j]){
21                 e[i][j] = e[i][x] + e[x][j];
22             }
23         }
24     }
25     /*for(i=0;i<n;i++){
26         for(j=0;j<n;j++){
27             printf("%9d",e[i][j]);
28         }
29         printf("\n");
30     }*/
31 }
32 int main()
33 {
34     int u,v,w,op,x,y,i,j,t=1;
35     while(scanf("%d%d%d",&n,&m,&q) == 3 && n+m+q != 0){
36         printf("Case %d:\n",t++);
37
38         for(i=0;i<n;i++){
39             for(j=0;j<n;j++){
40                 e[i][j] =  i==j?0:INF;
41             }
42         }
43
44         while(m--){
45             scanf("%d%d%d",&u,&v,&w);
46             if(e[u][v] > w)
47                 e[u][v] = w;
48         }
49         /*for(i=0;i<n;i++){
50             for(j=0;j<n;j++){
51                 printf("%9d",e[i][j]);
52             }
53             printf("\n");
54         }*/
55         memset(book,0,sizeof(book));
56         while(q--){
57             scanf("%d",&op);
58             if(op == 0){
59                 scanf("%d",&x);
60                 if(book[x])
61                     printf("City %d is already recaptured.\n",x);
62                 else{
63                     floyd(x);
64                     book[x]=1;
65                 }
66             }
67             else
68             {
69                 scanf("%d%d",&x,&y);
70                 if(book[x] == 0 || book[y] == 0){
71                     printf("City %d or %d is not available.\n",x,y);
72                     continue;
73                 }
74                 if(e[x][y] < INF)
75                     printf("%d\n",e[x][y]);
76                 else
77                     printf("No such path.\n");
78             }
79         }
80         printf("\n");
81     }
82     return 0;
83 }

原文地址:https://www.cnblogs.com/wenzhixin/p/8976501.html

时间: 2024-10-11 07:00:12

Emergency(山东省第一届ACM程序设计真题+Floyd算法变型)的相关文章

山东省第一届acm程序设计竞赛题解

缺c 计算几何没看 f一个模拟,不想写,难度不大,J,因为时间挺早的,题目都比较简单,没什么难度,组队出个8题还是轻松的 A:水题 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e3+5; 4 string s[maxn]; 5 6 bool judge(string s1,string s2){ 7 if(s1.length()>s2.length())return 1; 8 int len=s1.

山东省第一届ACM大学生程序设计竞赛(原题) 回顾 4.18

Phone Number 题目链接:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2151&cid=1172 题意很简单:给出N行电话号码,寻找有没有一串是另一串的前缀,有的话输出No,当然两个一样的也是No 题解:没有前缀0,直接用二维数组存,大循环就行了,用strcmp比较相等.不会超时. Hello World!     题目链接:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=215

sdut 2159 Ivan comes again!(2010年山东省第一届ACM大学生程序设计竞赛) 线段树+离散

先看看上一个题: 题目大意是: 矩阵中有N个被标记的元素,然后针对每一个被标记的元素e(x,y),你要在所有被标记的元素中找到一个元素E(X,Y),使得X>x并且Y>y,如果存在多个满足条件的元素,先比较X,选择X最小的那个,如果还是有很多满足条件的元素,再比较Y,选择Y最小的元素,如果不存在就输出两个-1: 分析: 直接暴力就行了 这个题目大意: 这个题是上个题的坚强版,每次会增加或减少一个点,仍然找到一个元素E(X,Y),使得X>x并且Y>y: 最多有200000次操作,每次只

sdut 2153 Clockwise (2010年山东省第一届ACM大学生程序设计竞赛)

题目大意: n个点,第i个点和第i+1个点可以构成向量,问最少删除多少个点可以让构成的向量顺时针旋转或者逆时针旋转. 分析: dp很好想,dp[j][i]表示以向量ji(第j个点到第i个点构成的向量)为终点的最大顺时针/逆时针向量数.状态转移方程为 dp[j][i] = max{dp[k][j]+1}. 问题个关键是如何判断2个向量是顺时针还是逆时针. 计算几何用的知识是求叉积和点积,叉积的作用是判断两个向量的左右(顺逆),点积的作用是判断两个向量的前后.举个例子,假设有2个向量v1,v2,‘*

2010年山东省第一届ACM大学生程序设计竞赛 Balloons (BFS)

题意 : 找联通块的个数,Saya定义两个相连是 |xa-xb| + |ya-yb| ≤ 1 ,但是Kudo定义的相连是 |xa-xb|≤1 并且 |ya-yb|≤1.输出按照两种方式数的联通块的各数.思路 : 按照第一种定义方式就只能是上下左右四个位置,而第二种则是周围那8个都是相连的. 1 #include <iostream> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <queue> 5

SDNU 1143.Ivan comes again!【山东省第一届ACM】【7月21】

Ivan comes again! Description The Fairy Ivan gave Saya three problems to solve (Problem F). After Saya finished the first problem (Problem H), here comes the second. This is the enhanced version of Problem H. There is a large matrix whose row and col

SDNU 1142.Hello World!【山东省第一届ACM】【7月21】

Hello World! Description We know that Ivan gives Saya three problems to solve (Problem F), and this is the first problem. "We need a programmer to help us for some projects. If you show us that you or one of your friends is able to program, you can p

笔试真题 ALBB-2015 算法工程师实习生 笔试真题 解析

1.用十进制计算30!(30的阶乘),将结果转换成3进制进行表示的话,该进制下的结果末尾会有____个0. [解析] 计算N!下3进制结果末尾有多少个0,其实就是计算3进制中的3被进位多少次,只要将N!因式分解成3^m*other,m就是答案.技巧性的解法就是m=N/3+N/(3^2)+N/(3^3)....+N(3^k) (k<=N/3) -- N=30:N/3+N/9+N/27=14. 2.小赵和小钱二人分别从寝室和图书馆同时出发,相向而行.过了一段时间后二人在中途相遇,小赵继续向图书馆前进

没有什么不可能—记山东省第六届ACM程序设计竞赛(退役总结帖)

大一下学期,第一次听说了ACM这个词,当时每周六也开设了培训课,但我好像一次也没有去过,当时对这个词并没有什么太大的印象.后来学院里引进了自己的OJ,那时候我连基本的输入输出格式都不懂,当经历了一堆的WA,TLE之后突然换来的一个AC竟带来了莫名的喜悦.后来学院举办了第一届ACM程序设计竞赛,我报名参加了新秀赛和团队赛.三个小时的新秀赛,当时貌似做出了三道,意外的拿到了一等奖,这也成为了我大学生活的一个重要转折点.四个小时的团队赛,做得很艰难,各种不会,最后只做出了一道,排在三等奖的末尾.比赛之