Always Late
Ajmat: | Have you noticed one member of team 13 comes late in almost every contest? |
Nejhum: | You mean the team of Mahbub, Moazzem and Yeamin? What's the problem with them? |
Ajmat: | All of them lives far away from BUET, and they always avoid the shortest path to BUET. |
Nejhum: | Are you kidding? Why would they do so? A computer science student won't ever do that. |
Ajmat: | They always avoids the shortest path. They believe that they always face the worst traffic jam on their shortest way to BUET. |
Nejhum: | That sounds crazy! |
Ajmat: | They are more crazy than you think they are. They always try to use the path whose length is smaller than or equal to that of any path to BUET except the shortest one. And for that, they sometimes visit the same junction more than once. |
Nejhum: | But they are not using the longest path. Then why are they late almost everyday? |
Ajmat: | That's because they have to spend a lot of time to find out which of the paths meet their criteria. Perhaps they don't know how to find out the second-shortest path. |
Nejhum: | I think we should solve this real problem in today's contest, instead of solving imaginary ones. |
Ajmat: | Let's try. |
Input
The first line of each test case contains two integers:
n (the number of junctions, 1 <
n < 100) and
r (the number of bi-directional roads connecting these junctions). The junctions are numbered with 0, 1, ...,
n-1. Each of the next
r lines (one for each road) contains three integers: two junction-numbers that the corresponding road connects and the length of the road in kilometers. The next line contains an integer
q, the number of queries. Each of the next
q lines contains two junction-numbers. There is a blank line after the
q queries. There is at most 1 road between each junction pair. A road always connects two different junctions. Length of a road is not less than 1km and not more than 100km.
Input is terminated by EOF.
Output
For each set of output, print the set # (1, 2, ? ) followed by
q lines, one for each query, each containing the length of the second-shortest path between the corresponding junctions. However, for the unsolvable queries, print a '?'.
Sample Input4 3 0 1 12 0 2 20 1 2 15 3 0 1 0 2 0 3 4 3 0 1 11 0 2 20 1 2 15 3 0 1 0 2 0 3 | Sample OutputSet #1 35 27 ? Set #2 33 26 ? |
Mustaq Ahmed. 12-07-2002.
题意:最是找次短路,每个点可以经过不止一次。
思路:一开始先用floyd算出两两之间的最短距离,然后用dfs算出次短的,dfs的时候判断dist+w[x][t] < ans[s][t](保证比最短路大的情况下)更新ans的值,最后得到的就是s到t的次短路。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
using namespace std;
const int inf = 1e8;
const int maxn = 100+5;
int n , m , q , ptr;
struct Node
{
int v;
int w;
Node *next;
}edge[maxn*maxn] , *first[maxn];
int w[maxn][maxn];
int ans[maxn][maxn];
void init()
{
memset(first,0,sizeof(first));
ptr = 0;
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < n ; ++j)
ans[i][j] = w[i][j] = inf;
}
void add(int x,int y,int w)
{
edge[++ptr].v = y;
edge[ptr].w = w;
edge[ptr].next = first[x];
first[x] = &edge[ptr];
}
void dfs(int s,int t,int x ,int dist)
{
if (ans[s][t] <= dist + w[x][t]) return;
if (w[s][t] < dist+w[x][t])
ans[s][t] = min(ans[s][t],dist+w[x][t]);
for (Node * p = first[x] ; p ; p=p->next)
{
int y = p->v;
dfs(s,t,y,dist+p->w);
}
}
void input()
{
int u , v;
while (m--)
{
scanf("%d%d",&u,&v);
scanf("%d",&w[u][v]);
w[v][u] = w[u][v];
add(u,v,w[u][v]);
add(v,u,w[v][u]);
}
for (int i = 0 ; i < n ; ++i) w[i][i] = 0;
for (int k = 0 ; k < n ; ++k)
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < n ; ++j)
w[i][j] = min(w[i][j],w[i][k]+w[k][j]);
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < n ; ++j) if (w[i][j] != inf)
dfs(i,j,i,0);
}
void solve()
{
scanf("%d",&q);
while (q--)
{
int u , v;
scanf("%d%d",&u,&v);
if (u < 0 || v < 0 || u >= n || v >= n || ans[u][v]>=inf) printf("?\n");
else printf("%d\n",ans[u][v]);
}
}
int main()
{
int k = 0;
while (scanf("%d%d",&n,&m)==2)
{
++k;
init();
input();
printf("Set #%d\n",k);
solve();
}
}