1. 程式人生 > >洛谷 P3906 Geodetic集合 題解

洛谷 P3906 Geodetic集合 題解

題目描述

圖G是一個無向連通圖,沒有自環,並且兩點之間至多隻有一條邊。我們定義頂點v,u最短路徑就是從v到u經過邊最少的路徑。所有包含在v-u的最短路徑上的頂點被稱為v-u的Geodetic頂點,這些頂點的集合記作I(v, u)。

我們稱集合I(v, u)為一個Geodetic集合。

例如下圖中,I(2, 5)={2, 3, 4, 5},I(1, 5)={1, 3, 5},I(2, 4)={2, 4}。

給定一個圖G和若干點對v,u,請你分別求出I(v, u)。

輸入輸出格式

輸入格式:

 

輸入檔案geo.in,第一行為兩個整數n,m,分別表示圖G的頂點數和邊數(頂點編號1-n,n≤40)。下接m行,每行兩個整數a,b表示頂點a和b之間有一條無向邊。

第m+2行有一個整數k,表示給定的點對數。下接k行,每行兩個整數v,u。。

 

輸出格式:

 

輸出檔案geo.out,共k行,每行對應輸入檔案中每一個點對v,u,按頂點編號升序輸出I(v, u)。同一行的每個數之間用空格分隔。

 

輸入輸出樣例

輸入樣例#1:

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

輸出樣例#1: 

2 3 4 5
1 3 5
2 4

 

 

 資料範圍告訴我們直接Floyd暴力跑就能過。然後就是一個敲模板和模擬的過程。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int Map[105][105],n,m,q,x,y;
int main()
{
	std::ios::sync_with_stdio(false);
	cin>>n>>m;
	memset(Map,11,sizeof(Map));
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		Map[x][y]=Map[y][x]=1;
		Map[x][x]=Map[y][y]=0;
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				Map[i][j]=min(Map[i][j],Map[i][k]+Map[k][j]);//Floyd
	cin>>q;
	for(int t=1;t<=q;t++)
	{
		cin>>x>>y;
		for(int i=1;i<=n;i++)
			if(Map[x][i]+Map[i][y]==Map[x][y])//如果點i在最短路徑中
				cout<<i<<' ';//直接輸出
		cout<<endl;
	}
	return 0;
}