NUC_HomeWork1 -- POJ2067(最短路)

C - Fire Station

Description

A city is served by a number of fire stations. Some residents have complained that the distance from their houses to the nearest station is too far, so a new station is to be built. You are to choose the location of the fire station so as to reduce the distance to the nearest station from the houses of the disgruntled residents. 
The city has up to 500 intersections, connected by road segments of various lengths. No more than 20 road segments intersect at a given intersection. The location of houses and firestations alike are considered to be at intersections (the travel distance from the intersection to the actual building can be discounted). Furthermore, we assume that there is at least one house associated with every intersection. There may be more than one firestation per intersection.

Input

The first line of input contains two positive integers: f,the number of existing fire stations (f <= 100) and i, the number of intersections (i <= 500). The intersections are numbered from 1 to i consecutively. f lines follow; each contains the intersection number at which an existing fire station is found. A number of lines follow, each containing three positive integers: the number of an intersection, the number of a different intersection, and the length of the road segment connecting the intersections. All road segments are two-way (at least as far as fire engines are concerned), and there will exist a route between any pair of intersections.

Output

You are to output a single integer: the lowest intersection number at which a new fire station should be built so as to minimize the maximum distance from any intersection to the nearest fire station.

Sample Input

1 6
2
1 2 10
2 3 10
3 4 10
4 5 10
5 6 10
6 1 10

Sample Output

5这是仿照人家写的SPFA,然后补上其他3个最短路算法

  1 /好长时间没写过最短路了,好多基础的东西都不记得了  c
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <algorithm>
  7 #include <queue>
  8
  9 using namespace std;
 10
 11
 12 const int N = 5050, INF = 10000;
 13
 14 int head[N], nc, n; ///
 15 int dis[N];         ///计算距离的数组
 16 int stk[N], f, r;   ///用数组模拟栈,
 17 bool vis[N];        ///在用spfa时的标记数组
 18
 19 struct Edge{        ///边
 20     int to, next, cost;
 21 }edge[100000];
 22
 23 void add(int a, int b, int c)  ///加边函数,双向
 24 {
 25     edge[nc].to = b;
 26     edge[nc].next = head[a];
 27     edge[nc].cost = c;
 28     head[a] = nc++;
 29
 30     edge[nc].to = a;
 31     edge[nc].next = head[b];
 32     edge[nc].cost = c;
 33     head[b] = nc++;
 34 }
 35
 36 void fire_spfa(int fire[], int num)
 37 {
 38     memset(vis, false, sizeof(vis));
 39
 40     f = r = 0;                      ///初始化栈
 41
 42     for(int i = 0; i < num; i++)    ///初始化每个消防站到其他点的距离
 43     {
 44         int t = fire[i];
 45         if(!vis[t])
 46         {
 47             vis[t] = true;
 48             dis[stk[r++] = t] = 0;///初始化,并将当前点入栈
 49         }
 50     }
 51
 52     while(f != r)               ///如果栈不为空
 53     {
 54         int now = stk[f++];     ///从栈中取出栈顶元素
 55         if(f == N) f = 0;       ///防止栈空间不够
 56
 57         vis[now] = false;       ///将当前结点标记
 58         for(int i = head[now]; i != -1; i = edge[i].next)   ///从边表中取出元素
 59         {
 60             int to = edge[i].to;
 61             int cot = edge[i].cost;
 62
 63             if(dis[to] > dis[now] + cot)                    ///进行松弛操作
 64             {
 65                 dis[to] = dis[now] + cot;
 66                 if(!vis[to])                                ///如果前驱没有访问过,
 67                 {
 68                     stk[r++] = to;                          ///入栈
 69                     if(r == N)
 70                         r = 0;
 71                     vis[to] = true;                         ///标记
 72                 }
 73             }
 74         }
 75     }
 76 }
 77
 78 int spfa(int src)
 79 {
 80     memset(vis, false, sizeof(vis));
 81     f = 0;
 82     r = 1;
 83
 84     vis[src] = true;
 85     int d[N];
 86     for(int i = 1; i <= n; ++i)     ///从当前结点到其余所有结点距离初始化
 87     {
 88         d[i] = INF;
 89     }
 90
 91     d[src] = 0;
 92     stk[0] = src;
 93
 94     while(f != r)
 95     {
 96         int now = stk[f++];
 97         if(f == N)
 98             f = 0;
 99         vis[now] = false;
100
101         for(int i = head[now]; i != -1; i = edge[i].next)
102         {
103             int to = edge[i]. to;
104             int cot = edge[i].cost;
105
106             if(d[to] > d[now] + cot)
107             {
108                 d[to] = d[now] + cot;
109                 if(!vis[to])
110                 {
111                     stk[r++] = to;
112                     vis[to] = true;
113                     if(r == N)
114                         r = 0;
115                 }
116             }
117         }
118     }
119
120     int ans = 0;
121     for(int i = 1; i <= n; ++i)
122     {
123         ans = max(ans, min(d[i], dis[i]));
124     }
125     return ans;
126 }
127
128 int main()
129 {
130     int ff, fire[N], a, b, c;
131
132     memset(head, -1, sizeof(head));
133     nc = 0;
134     scanf("%d%d", &ff, &n);
135     for(int i = 0; i < ff; ++i)
136     {
137         scanf("%d", fire+i);
138     }
139
140     while(scanf("%d%d%d", &a, &b, &c) != EOF)
141     {
142         add(a, b, c);
143     }
144
145     for(int i = 1; i <= n; ++i)
146         dis[i] = INF;
147
148     fire_spfa(fire, ff);
149
150     int id = 1, ans = INF;
151
152     for(int i = 1; i <= n; ++i)
153     {
154         if(dis[i] != 0)
155         {
156             int tp = spfa(i);
157             if(ans > tp)
158             {
159                 ans = tp;
160                 id = i;
161             }
162         }
163     }
164
165     printf("%d\n", id);
166     return 0;
167 }

时间: 2024-10-06 20:45:14

NUC_HomeWork1 -- POJ2067(最短路)的相关文章

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const

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

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<

ACM/ICPC 之 昂贵的聘礼-最短路解法(POJ1062)

//转移为最短路问题,枚举必经每一个不小于酋长等级的人的最短路 //Time:16Ms Memory:208K #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAX 105 int lim, n; int p[M

图论(A*算法,K短路) :POJ 2449 Remmarguts&#39; Date

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h

hdu4725 拆点+最短路

题意:有 n 个点,每个点有它所在的层数,最多有 n 层,相邻两层之间的点可以互相到达,消耗 c (但同一层并不能直接到达),然后还有一些额外的路径,可以在两点间互相到达,并且消耗一定费用.问 1 点到 n 点的最小花费 将每一层拆成两个点,分别为进入层和出发层,然后相邻层的出发层可以指向进入层,花费 c,每个点可以到达其出发层,而进入层可以到达该点,花费 0 ,最后建立其余双向边,最短路 1 #include<stdio.h> 2 #include<string.h> 3 #in

hdu3416 最短路+最大流

题意:有 n 点 m 边,有出发点 A 到达点 B ,只允许走原图中的最短路,但每条边只允许被走一次,问最多能找出多少条边不重复的最短路 一开始做到的时候瞎做了一发最短路,WA了之后也知道显然不对,就放着了,后来打了今年的多校,再做到的时候发现和多校第一场的1007一样的……最短路+网络流就行了,只不过第一次做这个的时候我还不知道网络流是啥,不会做也正常啦. 首先对于原图跑一遍最短路求出每个点距离 A 点的最短路,然后对于每一条边,如果它的权值等于它连接的两点的最短路的差值的时候,就说明这条路是

【啊哈!算法】算法7:Dijkstra最短路算法

上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图中的1号顶点到2.3.4.5.6号顶点的最短路径. <ignore_js_op> 与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下. <ignore_js_op> 我们还需要用一个一维数组dis来存储1号顶点到其余各个顶点的初始路程,如下.

HDU ACM 2544 最短路-&gt;最短路

最短路,简单题,floyd实现,在求最短路时一定要是是最大节点编号maxnum而不是输入的n,否则是错的. #include<iostream> using namespace std; int map[105][105]; //无向图 void Init() { int MAX=1000000,i,j; for(i=1;i<=104;i++) for(j=1;j<=104;j++) if(i==j) map[i][j]=0; else map[i][j]=MAX; } void