洛谷 P3906 Geodetic集合 題解
阿新 • • 發佈:2018-11-08
題目描述
圖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; }