图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)。
建一个边权值都为一的无相图,弗洛伊德算出最短路,然后再循环判断记录点就行了,没什么难度
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 int a[50][50],n,m,t,v,u,dian[50][50][50],sum[50][50]; 6 int main() 7 { 8 memset(a,10,sizeof(a)); 9 memset(sum,0,sizeof(sum)); 10 memset(dian,0,sizeof(dian)); 11 cin>>n>>m; 12 for(int i=1;i<=n;i++) a[i][i]=0; 13 for(int i=1;i<=m;i++) 14 { 15 int x,y; 16 scanf("%d%d",&x,&y); 17 a[x][y]=a[y][x]=1; 18 } 19 for(int k=1;k<=n;k++) 20 for(int i=1;i<=n;i++) 21 for(int j=1;j<=n;j++) 22 if(a[i][k]+a[k][j]<a[i][j]) 23 a[i][j]=a[i][k]+a[k][j]; 24 for(int k=1;k<=n;k++) 25 for(int i=1;i<=n;i++) 26 for(int j=1;j<=n;j++) 27 if(a[i][k]+a[k][j]==a[i][j]) 28 { 29 dian[i][j][++sum[i][j]]=k; 30 } 31 cin>>t; 32 for(int i=1;i<=t;i++) 33 { 34 scanf("%d%d",&v,&u); 35 for(int j=1;j<=sum[v][u];j++) 36 { 37 cout<<dian[v][u][j]<<' '; 38 } 39 cout<<endl; 40 } 41 return 0; 42 }