POJ3463 Sightseeing

Sightseeing

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 9535   Accepted: 3352

Description

Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the bus moves from one city S to another city F. On this way, the tourists in the bus can see the sights alongside the route travelled. Moreover, the bus makes a number of stops (zero or more) at some beautiful cities, where the tourists get out to see the local sights.

Different groups of tourists may have different preferences for the sights they want to see, and thus for the route to be taken from S to F. Therefore, Your Personal Holiday wants to offer its clients a choice from many different routes. As hotels have been booked in advance, the starting city S and the final city F, though, are fixed. Two routes from S to F are considered different if there is at least one road from a city A to a city B which is part of one route, but not of the other route.

There is a restriction on the routes that the tourists may choose from. To leave enough time for the sightseeing at the stops (and to avoid using too much fuel), the bus has to take a short route from S to F. It has to be either a route with minimal distance, or a route which is one distance unit longer than the minimal distance. Indeed, by allowing routes that are one distance unit longer, the tourists may have more choice than by restricting them to exactly the minimal routes. This enhances the impression of a personal holiday.

For example, for the above road map, there are two minimal routes from S = 1 to F = 5: 1 → 2 → 5 and 1 → 3 → 5, both of length 6. There is one route that is one distance unit longer: 1 → 3 → 4 → 5, of length 7.

Now, given a (partial) road map of the Benelux and two cities S and F, tour operator Your Personal Holiday likes to know how many different routes it can offer to its clients, under the above restriction on the route length.

Input

The first line of the input file contains a single number: the number of test cases to follow. Each test case has the following format:

  • One line with two integers N and M, separated by a single space, with 2 ≤ N ≤ 1,000 and 1 ≤ M ≤ 10, 000: the number of cities and the number of roads in the road map.
  • M lines, each with three integers A, B and L, separated by single spaces, with 1 ≤ A, BN, AB and 1 ≤ L ≤ 1,000, describing a road from city A to city B with length L.

    The roads are unidirectional. Hence, if there is a road from A to B, then there is not necessarily also a road from B to A. There may be different roads from a city A to a city B.

  • One line with two integers S and F, separated by a single space, with 1 ≤ S, FN and SF: the starting city and the final city of the route.

    There will be at least one route from S to F.

Output

For every test case in the input file, the output should contain a single number, on a single line: the number of routes of minimal length or one distance unit longer. Test cases are such, that this number is at most 109 = 1,000,000,000.

Sample Input

2
5 8
1 2 3
1 3 2
1 4 5
2 3 1
2 5 3
3 4 2
3 5 4
4 5 3
1 5
5 6
2 3 1
3 2 1
3 1 10
4 5 2
5 2 7
5 2 7
4 1

Sample Output

3
2

Hint

The first test case above corresponds to the picture in the problem description.

Source

BAPC 2006 Qualification

【题解】

用mi[0][i]和len[0][i]记录最短路和最短路条数

用mi[1][i]和len[1][i]记录严格次短路和严格次短路条数

用dijkstra,更新的时候最短路和次短路都要压入堆

转移即可(其他博客都有)

if(mi[0][v] == mi[d][u] + edge[pos].w) len[0][v] += len[d][u];
else if(mi[1][v] == mi[d][u] + edge[pos].w) len[1][v] += len[d][u];
else if(mi[0][v] > mi[d][u] + edge[pos].w)
	mi[1][v] = mi[0][v], len[1][v] = len[0][v];
	mi[0][v] = mi[d][u] + edge[pos].w, len[0][v] = len[d][u];
else if(mi[1][v] > mi[d][u] + edge[pos].w)
	mi[1][v] = mi[d][u] + edge[pos].w, len[1][v] = len[d][u];

我们这里着重来试着用显然法(唔)证明一下算法的正确性

看懂这部分你得先理解dijkstra的正确性证明。

不难发现从堆中一定先取出n个点的点最短路,再

取出n个点的次短路,所以每个点的mi[0],mi[1]

先被最短路更新mi[0]和mi[1],再被次短路更新mi[1]

不能只用最短路更新,可能会导致最短路=次短路的情况

大概理解dijkstra的证明,就能用显然法证mi(唔)

我们看len的证明

从小数据看,我们不妨虚设一个点0,使得起点s指向0,边权为0,s的出边全部变为

0的出边,s的入边还是s的入边。与原图等价。我们把0和s缩成一个点,len[0][s] = 1,

len[1][s]= 0 就是正确的

归纳证明

当我们取出len[0][u]或len[1][u]时,他们已经不可能被更新了,我们假定他们的值是正确的

对于u指出的所有点v

len[0][v]可能被更新,len[1][v]也可能被更新

v可能被所有指向他的点更新,更新他的点都是正确的

那么当v被取出的时候,没有点可以更新它了,v是正确的

证毕

注意用else,不然可能会更新乱掉

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <vector>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <queue>
  7 #define max(a, b) ((a) > (b) ? (a) : (b))
  8 #define min(a, b) ((a) < (b) ? (a) : (b))
  9 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
 10
 11 const int INF = 0x3f3f3f3f;
 12 const int MAXN = 1000 + 10;
 13 const int MAXM = 100000 + 10;
 14
 15 inline void read(int &x)
 16 {
 17     x = 0;char ch = getchar(), c = ch;
 18     while(ch < ‘0‘ || ch > ‘9‘) c = ch, ch = getchar();
 19     while(ch <= ‘9‘ && ch >= ‘0‘) x = x * 10 + ch - ‘0‘, ch = getchar();
 20     if(c == ‘-‘)x = -x;
 21 }
 22
 23 struct Edge
 24 {
 25     int u,v,w,next;
 26     Edge(int _u, int _v, int _w, int _next){u = _u;v = _v;w = _w;next = _next;}
 27     Edge(){}
 28 }edge[MAXM << 1];
 29 int head[MAXN], cnt;
 30 inline void insert(int a, int b, int c)
 31 {
 32     edge[++cnt] = Edge(a,b,c,head[a]);
 33     head[a] = cnt;
 34 }
 35
 36 int tt,n,m,s,t;
 37
 38 struct Node
 39 {
 40     int v,w,d;
 41     Node(int _v, int _w, int _d){v = _v;w = _w;d = _d;}
 42     Node(){}
 43 };
 44
 45 int mi[2][MAXN], len[2][MAXN],b[2][MAXN];
 46
 47 struct cmp
 48 {
 49     bool operator()(Node a, Node b)
 50     {
 51         return a.w > b.w;
 52     }
 53 };
 54
 55 std::priority_queue<Node, std::vector<Node>, cmp> q;
 56
 57 void dijstra()
 58 {
 59     while(q.size())q.pop();
 60     memset(mi, 0x3f, sizeof(mi));
 61     memset(len, 0, sizeof(len));
 62     memset(b, 0, sizeof(b));
 63     len[0][s] = 1;
 64     mi[0][s] = 0;
 65     q.push(Node(s, 0, 0));
 66     int u,v,d;Node now;
 67     while(q.size())
 68     {
 69         now = q.top();q.pop();
 70         if(b[now.d][now.v])continue;
 71         b[now.d][now.v] = 1;
 72         u = now.v;d = now.d;b[d][u] = 1;
 73         for(register int pos = head[u];pos;pos = edge[pos].next)
 74         {
 75             v = edge[pos].v;
 76             if(mi[0][v] == mi[d][u] + edge[pos].w) len[0][v] += len[d][u];
 77             else if(mi[1][v] == mi[d][u] + edge[pos].w) len[1][v] += len[d][u];
 78             else if(mi[0][v] > mi[d][u] + edge[pos].w)
 79             {
 80                 mi[1][v] = mi[0][v], len[1][v] = len[0][v];
 81                 mi[0][v] = mi[d][u] + edge[pos].w, len[0][v] = len[d][u];
 82                 q.push(Node(v, mi[0][v], 0));
 83                 q.push(Node(v, mi[1][v], 1));
 84             }
 85             else if(mi[1][v] > mi[d][u] + edge[pos].w)
 86             {
 87                 mi[1][v] = mi[d][u] + edge[pos].w, len[1][v] = len[d][u];
 88                 q.push(Node(v, mi[1][v], 1));
 89             }
 90         }
 91     }
 92 }
 93
 94 int main()
 95 {
 96     read(tt);
 97     for(;tt;--tt)
 98     {
 99         memset(edge, 0, sizeof(edge));
100         memset(head, 0, sizeof(head));
101         cnt = 0;
102         read(n), read(m);
103         int tmp1, tmp2, tmp3;
104         for(register int i = 1;i <= m;++ i)
105         {
106             read(tmp1), read(tmp2), read(tmp3);
107             insert(tmp1, tmp2, tmp3);
108         }
109         read(s), read(t);
110         dijstra();
111         if(mi[0][t] + 1 == mi[1][t])
112             printf("%d\n", len[0][t] + len[1][t]);
113         else
114             printf("%d\n", len[0][t]);
115     }
116     return 0;
117 }

POJ3463

时间: 2024-10-12 03:47:11

POJ3463 Sightseeing的相关文章

poj3463 Sightseeing --- dij最短路和次短路

最短路好题啊. 题目给定起点和终点,要求最短路和次短路(要求次短路只比最短路大1)的道路数量. 重点在于次短路如何处理是最高效的呢 这就要求对dij算法路径更新的理解了. 我们用一个数组记录最短路,一个数组记录次短路. 每次对当前最短边,先更新最短路,更新不了最短路再更新次短路. 每条边处理两次,这样就可以在2n×n的复杂度内求得最短路和次短路了. #include<cstdio> #include<cstring> #include<queue> #include&l

[POJ3463] Sightseeing(次短路 Heap + Dijkstra)

传送门 用dijkstra比较好,spfa可能有的重复 dis[x][2]:dis[x][0]表示起点到x的最短路.dis[x][1]表示起点到x的次短路: tot[x][2]:tot[x][0]表示起点到x的最短路条数.tot[x][1]表示起点到x的次短路的条数: vis[x][2]对应于x和0.1功能为记录该点是否被访问! 那么如何更新最小和次小路呢?显然我们容易想到下面的方法: 1.if(x<最小)更新最小,次小:2.else if(x==最小)更新方法数:3.else if(x<次小

poj3463 Sightseeing——次短路计数

题目:http://poj.org/problem?id=3463 次短路计数问题,在更新最短路的同时分类成比最短路短.长于最短路而短于次短路.比次短路长三种情况讨论一下,更新次短路: 然而其实不必被"同时"限制,否则就容易像我一开始一样写挂... 像拆点一样把最短路和次短路完全分开,放进 dijkstra 的优先队列里,真是巧妙: 还要注意一点是直接更新最短路之后要把它的次短路也加进优先队列里,因为次短路同时也被更新了. 代码如下: #include<iostream>

poj1734 Sightseeing trip

Sightseeing trip Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6919   Accepted: 2646   Special Judge Description There is a travel agency in Adelton town on Zanzibar island. It has decided to offer its clients, besides many other attra

POJ 1637 Sightseeing tour (混合图欧拉回路)

Sightseeing tour Description The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can see every corner of the beautiful city. They want to construct the tour so that every street in the city is visit

1999 Central European Olympiad in Informatics - Sightseeing Trip

算法提示 最小环问题 题目大意 在一张带权无向图上,找出至少含 3 个点且权值和最小的环,并按环上的循序输出环上的点.存在重边,无自环. 做法分析 参考最小环问题,在更新 dist[i][j] 时,记录更新其的点 k,便于回溯路径. 参考代码 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <queue> 5 #include <algorithm> 6

HDU1688 Sightseeing(SPFA 求最短路与次短路的路径条数)可用作模板

Sightseeing Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 718    Accepted Submission(s): 293 Problem Description Tour operator Your Personal Holiday organises guided bus trips across the Bene

poj3621 Sightseeing Cows --- 01分数规划

典型的求最优比例环问题 参考资料: http://blog.csdn.net/hhaile/article/details/8883652 此题中,给出每个点和每条边的权值,求一个环使 ans=∑点权/∑边权 最大. 因为题目要求一个环,而且必然是首尾相接的一个我们理解的纯粹的环,不可能是其他样子的环, 所以我们可以把一条边和指向的点看做整体处理. 上面方程可以化为:ans×e[i]-p[i]=0 以它为边权二分答案,spfa求负环,有负环则该ans可行,增大下界. 若一直不可行,则无解. #i

POJ 1734:Sightseeing trip

Sightseeing trip Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6831 Accepted: 2612 Special Judge Description There is a travel agency in Adelton town on Zanzibar island. It has decided to offer its clients, besides many other attractions