POJ1122_FDNY to the Rescue!(逆向建图+最短路树)

FDNY to the Rescue!

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 2368   Accepted: 721

Description

The Fire Department of New York (FDNY) has always been proud of their response time to fires in New York City, but they want to make their response time even better. To help them with their response time, they want to make sure that the dispatchers know the
closest firehouse to any address in the city. You have been hired to write this software and are entrusted with maintaining the proud tradition of FDNY. Conceptually, the software will be given the address of the fire, the locations of the firehouses, street
intersections, and the time it takes to cover the distance between each intersection. It will then use this information to calculate how long it takes to reach an address from each firehouse.

Given a specific fire location in the city, the software will calculate the time taken from all the fire stations located in the city to reach the fire location. The list of fire stations will be sorted from shortest time to longest time. The dispatcher can
then pick the closest firestation with available firefighters and equipment to dispatch to the fire.

Input

Line 1:

# of intersections in the city, a single integer (henceforth referred to as N) N<20

Lines 2 to N+1:

A table (square matrix of integer values separated by one or more spaces) representing the time taken in minutes between every pair of intersections in the city. In the sample input shown below the value "3" on the 1st row and the 2nd column represents the
time taken from intersection #1 to reach intersection #2.

Similarly the value "9" on the 4th row and the 2nd column represents the time taken from intersection #4 to reach intersection #2.

A value of -1 for time means that it is not possible to go directly from the origin intersection (row #) to the destination intersection (column #). All other values in the table are non-negative.

Line N+2:

An integer value n (<= N) indicating the intersection closest to the fire location followed by one or more integer values for the intersections closest to the fire stations (all on one line, separated by one or more spaces) will follow the input matrix.

Notes on input format:

1. The rows and columns are numbered from 1 to N.

2. All input values are integers

3. All fire locations are guaranteed reachable from all firehouses.

4. All distance calculations are made from the intersection closest to each firehouse to the intersection closest to the fire.

Output

Line 1:

A label line with the headings for each column, exactly as shown in the example.

Line 2 onwards (one line for each fire station):

A sorted list (based on time) showing the fire station (origin), the destination site, time taken and a complete shortest path of nodes from the originating fire station to the fire location.

Notes on output format:

1. Columns are tab separated.

2. If two or more firehouses are tied in time they can be printed in any order.

3. If more than one path exists that has the same minimal time for a given location & firehouse, either one can be printed on the output.

4. If the fire location and the fire station locations happen to be the same intersection, the output will indicate that the origin and destination have the same intersection number, the time will be "0" and the nodes in the shortest path will show just one
number, the fire location.

Next is the picture for the sample input data.

Sample Input

6
0  3  4 -1 -1 -1
-1 0  4  5 -1 -1
2  3  0 -1 -1  2
8  9  5  0  1 -1
7  2  1 -1  0 -1
5 -1  4  5  4  0
2  4  5  6
In the above input the last line indicates that "2" is the location of the fire and "4", "5" and "6" are the intersections where fire stations are located. 

Sample Output

Org	Dest	Time	Path
5	2	2	5	2
4	2	3	4	5	2
6	2	6	6	5	2

Source

Mid-Atlantic 2001

解题报告

下午RE了下午,莫名的心烦。。。(心烦是不是下午模拟邀请赛挂零了。。。)

晚上回宿舍重新敲上一遍,AC。。。

这题要处理建图的关系,虽然图是无向图,但i到j的时间并不是j到i的时间,灭火大队又要从消防站出发到达火源,而火源是固定的,所以逆向建图是最好的处理,找从火源出发到达消防站的最短时间。

二是这题要打印路径,很少碰到这类题目,其实就是利用数组来处理树的关系,数组储存的是当前序号节点的父节点,一次找下去,就是遍历路径树。。。

其中处理最短路是最裸的最短路。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 99999999
#define Max 30
using namespace std;
int n,mmap[Max][Max],dis[Max],vis[Max],pre[Max];
struct node
{
    int org,dest,time;
} num[Max];
int cmp(node a,node b)
{
    return a.time<b.time;
}
void dij(int s)
{
    int i,j,u,minn;
    for(i=1; i<=n; i++)
    {
        dis[i]=mmap[s][i];
        vis[i]=0;
        if(i!=s)
            pre[i]=s;
        else pre[i]=-1;
    }
    dis[s]=0;
    vis[s]=1;
    for(i=0; i<n-1; i++)
    {
        u=0;
        minn=inf;
        for(j=1; j<=n; j++)
        {
            if(!vis[j]&&dis[j]<minn)
            {
                minn=dis[j];
                u=j;
            }
        }
        vis[u]=1;
        for(j=1; j<=n; j++)
        {
            if(!vis[j]&&dis[j]>dis[u]+mmap[u][j])
            {
                dis[j]=dis[u]+mmap[u][j];
                pre[j]=u;
            }
        }
    }
}
int main()
{
    int i, j, s, u, cnt=0;
    cin>>n;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=n; j++)
        {
            scanf("%d",&mmap[j][i]);
            if(mmap[j][i]==-1)
                mmap[j][i]=inf;
        }
    }
    cin>>s;
    dij(s);
    while(cin>>u)
    {
        num[cnt].org=u;
        num[cnt].dest=s;
        num[cnt++].time=dis[u];
    }
    printf("Org\tDest\tTime\tPath\n");
    int shortest[Max];
    sort(num,num+cnt,cmp);
    for(i=0; i<cnt; i++)
    {
        printf("%d\t%d\t%d",num[i].org,num[i].dest,num[i].time);
        memset(shortest,0,sizeof(shortest));
        int k=0;
        shortest[k]=num[i].org;
        while(pre[shortest[k]]!=-1)
        {
            k++;
            shortest[k]=pre[shortest[k-1]];
        }
//        k++;
//        shortest[k]=s;
        for(j=0;j<=k;j++)
        printf("\t%d",shortest[j]);
        printf("\n");
    }
    return 0;
}

POJ1122_FDNY to the Rescue!(逆向建图+最短路树),布布扣,bubuko.com

时间: 2024-12-11 22:44:24

POJ1122_FDNY to the Rescue!(逆向建图+最短路树)的相关文章

hdu 4857/BestCoder Round#1 1001(拓扑排序+逆向建图)

此题需细致分析题目,否则题意easy理解错误.应注意以下这样的情况 本题意思尽可能让最小的排的靠前.然后次小的尽量靠前.依次下去 如 input: 1 3 1 3 1 output: 3 1 2 解析:我们应让1尽可能的排在前面.然后尽可能的让2排的靠前.. .所以 2 3 1的结果是错误的 思路:拓扑排序(逆向建图+队列)//为解决上述列子.假设我们正向建图.每次选择入度为零最小的编号输出则无法满足上述案例. 假设我们尝试逆向建图,每次选择入度为零的最大编号输出则刚刚是正确结果的逆序(省赛并查

hdu 4857 逃生 拓扑排序+逆向建图

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处. 负责人现在

hdu 4857/BestCoder Round#1 1001(逆向建图)

此题需仔细分析题目,否则题意容易理解错误,应注意下面这种情况 本题意思尽可能让最小的排的靠前,然后次小的尽量靠前,依次下去 如 input: 1 3 1 3 1 output: 3 1 2 解析:我们应让1尽可能的排在前面,然后尽可能的让2排的靠前...所以 2 3 1的结果是错误的 思路:拓扑排序(逆向建图+队列)//为解决上述列子,如果我们正向建图,每次选择入度为零最小的编号输出则无法满足上述案例: 如果我们尝试逆向建图,每次选择入度为零的最大编号输出则刚刚是正确结果的逆序(省赛并查集的逆用

hdu 4857 逆向建图+拓扑排序 ***

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

UVA 1416 - Warfare And Logistics(最短路树)

UVA 1416 - Warfare And Logistics 题目链接 题意:给定一个无向图,每个边一个正权,c等于两两点最短路长度之和,现在要求删除一边之后,新图的c值最大的是多少 思路:直接枚举删边,每次做一次dijkstra的话复杂度太高,其实如果建好最短路树,如果删去的边在最短路树上,才需要去做,这样复杂度就优化到(n^2mlog(n)),勉强可以接受 代码: #include <cstdio> #include <cstring> #include <vecto

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

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

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

HDU 5521 [图论][最短路][建图灵感]

/* 思前想后 还是决定坚持写博客吧... 题意: n个点,m个集合.每个集合里边的点是联通的且任意两点之间有一条dis[i]的边(每个集合一个dis[i]) 求同时从第1个点和第n个点出发的两个人相遇的最短时间,并输出相遇的地点,如果有多个按编号大小顺序输出. 输入: 测试数据 t n m 以下m行每行 dis[i] 该集合点的数量 ...每个点的标号 数据范围: n 2-1e5 所有集合的元素的数量和 1e6 思路: 如果直接跑最短路,边会存爆的. 考虑换种思路建边. 每个集合看作两个点,一

POJ 2312Battle City(BFS-priority_queue 或者是建图spfa)

1 /* 2 bfs搜索!要注意的是点与点的权值是不一样的哦! 3 空地到空地的步数是1, 空地到墙的步数是2(轰一炮+移过去) 4 所以用到优先队列进行对当前节点步数的更新! 5 */ 6 #include<iostream> 7 #include<queue> 8 #include<cstring> 9 #include<algorithm> 10 #include<cstdio> 11 using namespace std; 12 13