luogu P1078 文化之旅 dfs floyd
我们当前在点x,已经走了路径为len的长度。准备到i点。 那么从x到i,在刚刚floyd不完全的考虑文化影响的前提下,最短路为mp[x][i]。 从i到t,在刚刚floyd不完全的考虑文化影响的前提下,最短路为mp[i][t]。 如果len + mp[x][t]+mp[x][i] 都长于当前已经搜到的最优ans。 那么显然从x到i这一步是没有意义的,就可以剪枝了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int MAXN = 110; 6 int ans,n,k,m,s,t; 7 int c[MAXN],map[MAXN][MAXN],q[MAXN]; 8 bool b[MAXN][MAXN],flag[MAXN]; 9 void dfs(int x,int len) 10 { 11 if(x == t) 12 { 13 ans = min(ans,len); 14 return; 15 } 16 int l,r; 17 for(int i = 1; i <= n; i++) 18 if(!flag[i] && ans - len - map[x][i] > map[i][t]) 19 { 20 l = q[0] + 1; 21 q[++q[0]] = i; 22 flag[i] = 1; 23 for(int j = 1; j <= n; j++) 24 if(!flag[j] && b[c[j]][c[i]]) 25 { 26 q[++q[0]] = j; 27 flag[j] = 1; 28 } 29 r = q[0]; 30 dfs(i,len + map[x][i]); 31 for(int j = l; j <= r; j++) 32 flag[q[j]] = 0; 33 q[0] = l - 1; 34 } 35 } 36 void floyd() 37 { 38 for(int k = 1; k <= n; k++) 39 for(int i = 1; i <= n; i++) 40 if(!b[c[k]][c[i]]) 41 for(int j = 1; j <= n; j++) 42 if(!b[c[j]][c[k]] && !b[c[j]][c[i]]) 43 if(map[i][j] - map[i][k] > map[k][j]) 44 map[i][j] = map[i][k] + map[k][j]; 45 } 46 int main() 47 { 48 scanf("%d%d%d%d%d",&n,&k,&m,&s,&t); 49 for(int i = 1; i <= n; i++) 50 scanf("%d",&c[i]); 51 for(int i = 1; i <= k; i++) 52 for(int j = 1; j <= k; j++) 53 scanf("%d",&b[i][j]); 54 for(int i = 1; i <= k; i++) 55 b[i][i] = 1; 56 if(b[c[t]][c[s]]) 57 { 58 printf("-1\n"); 59 return 0; 60 } 61 memset(map,0x1f,sizeof(map)); 62 int tu,tv,td; 63 for(int i = 1; i <= m; i++) 64 { 65 scanf("%d%d%d",&tu,&tv,&td); 66 map[tu][tv] = map[tv][tu] = td; 67 } 68 for(int i = 1; i <= n; i++) 69 map[i][i] = 0; 70 floyd(); 71 for(int i = 1;i <= n;i++) 72 if(i != s && i != t) 73 if(b[c[i]][c[s]] || b[c[t]][c[i]]) 74 { 75 q[++q[0]] = i; 76 flag[i] = 1; 77 } 78 ans = map[0][0]; 79 q[++q[0]] = s; 80 flag[s] = 1; 81 dfs(s,0); 82 if(ans == map[0][0]) 83 printf("-1\n"); 84 else 85 printf("%d\n",ans); 86 return 0; 87 }
心之所动 且就随缘去吧