poj1122 FDNY to the Rescue!(dij+反向建图+输出路径)

题目链接:poj1122 FDNY to the Rescue!

题意:给出矩阵,矩阵中每个元素tij表示从第i个交叉路口到第j个交叉路口所需时间,若tij为-1则表示两交叉路口之间没有直接路径,再给出火警位置所在的交叉路口 和 一个或多个消防站所处的交叉路口位置。输出要求按消防站到火警位置所需时间从小到大排列,输出信息包括消防站位置(初始位置),火警位置(目标位置),所需时间,最短路径上每个交叉路口。

题解:反向建图,从火警位置求一次最短路,求最短路时记录路径,按时间从小到大输出。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define CLR(a,b) memset((a),(b),sizeof((a)))
 5 using namespace std;
 6
 7 const int inf = 0x3f3f3f3f;
 8 const int N = 21;
 9 int n, fire;
10 int g[N][N];//邻接矩阵存图
11 int s[N], d[N];
12 int path[N];//表示v0到vi最短路径顶点vi的前一个顶点序号
13 int shortest[N];//存储最短路径上的各个顶点序号
14 struct node{
15     int u, v, t;
16 }a[N];
17 int cmp(node a, node b){
18     return a.t < b.t;
19 }
20 void dij(){
21     int i, j, k;
22     CLR(s, 0);
23     for(i = 1; i <= n; ++i){
24         d[i] = g[fire][i];
25         if(i != fire)
26             path[i] = fire;
27         else
28             path[i] = -1;
29     }
30     s[fire] = 1;
31     d[fire] = 0;
32     for(i = 0; i < n-1; ++i){
33         int mi = inf, u = 0;
34         for(j = 1; j <= n ; ++j){
35             if(!s[j] && d[j] < mi){
36                 u = j; mi = d[j];
37             }
38         }
39         s[u] = 1;
40         for(k = 1; k <= n; ++k){
41             if(!s[k] && d[u] + g[u][k] < d[k]){
42                 d[k] = d[u] + g[u][k];
43                 path[k] = u;
44             }
45         }
46     }
47 }
48 int main(){
49     int i, j, x, cnt;
50     scanf("%d", &n);
51     for(i = 1; i <= n; ++i){//边反向存储
52         for(j = 1; j <= n; ++j){
53             scanf("%d", &x);
54             if(x == -1)
55                 g[j][i] = inf;
56             else
57                 g[j][i] = x;
58         }
59     }
60     scanf("%d", &fire);
61     dij();
62     cnt = 0;
63     while(scanf("%d", &x) == 1){
64         a[cnt].u = x;
65         a[cnt].v = fire;
66         a[cnt++].t = d[x];
67     }
68     sort(a, a+cnt, cmp);
69     printf("Org\tDest\tTime\tPath\n");
70     for(i = 0; i < cnt; ++i){
71         printf("%d\t%d\t%d", a[i].u, a[i].v, a[i].t);
72         CLR(shortest, 0);
73         int k = 0;//表示shortest数组中最后一个元素的下标
74         shortest[k] = a[i].u;
75         while(path[shortest[k]] != -1){
76             k++;
77             shortest[k] = path[shortest[k-1]];
78         }
79         for(j = 0; j <= k; ++j) //倒向追踪,但是反向建图,因此正向输出
80             printf("\t%d", shortest[j]);
81         puts("");
82     }
83     return 0;
84 }

时间: 2024-10-09 23:48:35

poj1122 FDNY to the Rescue!(dij+反向建图+输出路径)的相关文章

HDU2647(拓扑排序+反向建图)

题意不说了,说下思路. 给出的关系是a要求的工资要比b的工资多,由于尽可能的让老板少付钱,那么a的工资就是b的工资+1,可以确定关系为a>b,根据拓扑排序建边的原则是把"小于"关系看成有向边,那么我们可以建边v->u. #include <stdio.h> #include <string.h> #include <string> #include <iostream> #include <algorithm> #

HDU1535Invitation Cards(有向图,正向建图和反向建图各spfa一次)

Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2374    Accepted Submission(s): 1151 Problem Description In the age of television, not many people attend theater performances.

POJ 3687 反向建图+拓扑

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11146   Accepted: 3192 Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that: No two balls share

HDU4857——逃生(反向建图+拓扑排序)

逃生 Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处.负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推.那么你就要安排大家的顺序.我们保证一

HDU 3639 Hawk-and-Chicken(强连通缩点+反向建图)

http://acm.hdu.edu.cn/showproblem.php?pid=3639 题意: 有一群孩子正在玩老鹰抓小鸡,由于想当老鹰的人不少,孩子们通过投票的方式产生,但是投票有这么一条规则:投票具有传递性,A支持B,B支持C,那么C获得2票(A.B共两票),输出最多能获得的票数是多少张和获得最多票数的人是谁? 思路: 先强连通缩点反向建图,在计算强连通的时候,需要保存每个连通分支的结点个数. 为什么要反向建图呢?因为要寻找票数最多的,那么肯定是入度为0的点,然后dfs计算它的子节点的

[CF825E] Minimal Labels(反向建图,拓扑排序)

题目链接:http://codeforces.com/problemset/problem/825/E 题意:给一个有向图,求一个排列,这个排列是每一个点的序号,使得序号对应的点的排序符合拓扑序并且这个排列字典序最小. 直接跑字典序最小的拓扑排序是不行的,因为那样只是确保点的字典序而非这个排列的字典序,比如这个数据: 10 15 2 反过来考虑,点号大的入度为0的点一定排在后面,这个位置确定了.但是点好小的入度为0的未必一定排在前面,因为这个点之前可能有入度不为0,但是与此点无关的点在前面,按题

强连通 反向建图 hdu3639

Hawk-and-Chicken Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3321    Accepted Submission(s): 1041 Problem Description Kids in kindergarten enjoy playing a game called Hawk-and-Chicken. But t

hdu 1535 Invitation Cards(有向图的来回最短路,要反向建图)

题目: 链接:点击打开链接 题意: 给一个图,求1到各点和各点到1最短路. 思路: 先spfa,然后反向建图,在spfa就行了. 代码: #include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; #define INF 100000000 const int N = 1000010; struct node{ int u,v,w

HDU 2680 Choose the best route &lt;SPFA算法+反向建图&gt;

Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10690    Accepted Submission(s): 3454 Problem Description One day , Kiki wants to visit one of her friends. As she is liabl