分析
求任意两点间的最短路,容易想到是Floyd,怎么存中间路径,直接用longlong压缩存就好
注意相同长度的路径要更新路径
代码
1 /******************** 2 User:Mandy.H.Y 3 Language:c++ 4 Problem:luogu3906 5 ********************/ 6 7 #include<bits/stdc++.h> 8 9 using namespace std; 10 11 const int maxn = 45; 12 13 int n,m; 14 int g[maxn][maxn]; 15 long long a[maxn][maxn]; 16 17 template<class T>inline void read(T &x){ 18 x = 0;bool flag = 0;char ch = getchar(); 19 while(!isdigit(ch)) flag |= ch == '-',ch = getchar(); 20 while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar(); 21 if(flag) x = -x; 22 } 23 24 template<class T>void putch(const T x){ 25 if(x > 9) putch(x / 10); 26 putchar(x % 10 | 48); 27 } 28 29 template<class T>void put(const T x){ 30 if(x < 0) putchar('-'),putch(-x); 31 else putch(x); 32 } 33 34 void file(){ 35 freopen("3906.in","r",stdin); 36 freopen("3906.out","w",stdout); 37 } 38 39 void readdata(){ 40 read(n);read(m); 41 memset(g,0x3f3f3f3f,sizeof(g)); 42 for(int i = 1;i <= m; ++ i){ 43 int u,v; 44 read(u);read(v); 45 g[u][v] = g[v][u] = 1; 46 } 47 for(int i = 1;i <= n; ++ i) g[i][i] = 0; 48 } 49 50 void Floyd(){ 51 for(int k = 1; k <= n; ++ k){ 52 for(int i = 1;i <= n; ++ i){ 53 for(int j = 1;j <= n; ++ j){ 54 if(g[i][k] + g[k][j] < g[i][j]){ 55 a[i][j] = (a[i][k] | a[k][j]) | (1LL << k); 56 a[j][i] = a[i][j]; 57 g[i][j] = g[i][k] + g[k][j]; 58 g[j][i] = g[i][j]; 59 } else if(g[i][k] + g[k][j] == g[i][j]){ 60 a[i][j] |= ((a[i][k] | a[k][j]) | (1LL << k)); 61 a[j][i] = a[i][j]; 62 } 63 } 64 } 65 } 66 } 67 68 void work(){ 69 70 Floyd(); 71 int k;read(k); 72 73 for(int i = 1;i <= k; ++ i){ 74 int u,v; 75 read(u);read(v); 76 a[u][v] = a[u][v] | (1LL << u) | (1LL << v); 77 for(int i = 1;i <= n; ++ i){ 78 if((1LL << i) & a[u][v]){ 79 put(i); 80 putchar(' '); 81 } 82 } 83 puts(""); 84 } 85 86 } 87 88 int main(){ 89 // file(); 90 readdata(); 91 work(); 92 return 0; 93 }