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

洛谷P3906 Geodetic集合解題報告

Geodetic集合

P3906

技術統計

難度

提高+/省選-

用時

30min

提交次數 1

unaccept 次數 0

ac次數 1

題意概括

題幹不能再概括了啊啊啊啊

資料範圍

n<=40n<=40

解法、

知識點

  1. floyd
  2. 最短路

解法概括

我欺負它資料範圍小,就直接跑floyd咯。然後列舉1~n所有的點,若存在dis[i][k]+dis[k][j]==dis[i][j],則ans++。個人認為這裡是floyd演算法的逆應用。

坑點

  1. 一定要建雙向邊
  2. 每次統計完後別忘記sort一下,以防萬一

程式碼實現

#include<cstdio>
#include<algorithm> #include<cstring> #define inf 40 using namespace std; int n,m; int vis[50]; int f[50][50]; inline int read() { int f=1,k=0; char c=getchar(); while(c>'9'||c<'0') { if(c=='-')f=-1; c=getchar(); } while(c>='0'&&c<='9'
)k=(k<<1)+(k<<3)+(c^48),c=getchar(); return f*k; } void floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=min(f[i][j],f[i][k]+f[k][j]); } int main() { n=read();m=read(); memset(f,inf,sizeof(f)); for(int i=1;i<=
m;i++) { int a=read(),b=read(); f[a][b]=f[b][a]=1; } floyd(); int q=read(); for(int i=1;i<=q;i++) { memset(vis,0,sizeof(vis)); int a=read(),b=read(),cnt=0; vis[++cnt]=a; for(int j=1;j<=n;j++) if(f[a][j]+f[j][b]==f[a][b])vis[++cnt]=j; vis[++cnt]=b; sort(vis+1,vis+cnt+1); for(int j=1;j<cnt;j++)printf("%d ",vis[j]); printf("%d\n",vis[cnt]); } }

類似題目

還沒做到qwq(本來這裡我想打ye的,但是沒找到,,結果發現了“吔”,,,果然b站不能完全相信QAQ)