Preguntas sobre el cepillado diario 35

Límite de recursos
Límite de memoria: 256,0 MB Límite de tiempo de C/C++: 1,0 s Límite de tiempo de Java: 3,0 s Límite de tiempo de Python:   5,0 s
Descripción
Debido a que Dou Zhipeng es demasiado divertido, durante este período de tiempo, la niña usó sus habilidades para causar problemas contra Dou Zhipeng y fue a visitar muchos lugares pintorescos. Debido a que Dou Zhipeng pasó demasiado tiempo dibujando la máquina antes, y pronto tendrá una prueba de cálculo, por lo que ahora la chica lo lleva a un estado de locura. Pero la niña siempre es Dios, por lo que Dou Zhipeng solo puede llevarla a jugar, pero para ahorrar tiempo, espera encontrar una ruta turística única que tome el menor tiempo.
Formato de entrada
  La primera línea contiene un número n, que indica cuántos lugares escénicos hay en la ciudad donde se encuentra Dou Zhipeng, y la siguiente es una matriz n * n. a (i, j) representa el tiempo transcurrido en el camino desde el lugar escénico i al lugar escénico j.
  El siguiente es un número m, que indica la cantidad de atracciones que visitará la hermana de Dou Zhipeng. Debido a que la chica está causando problemas sin ningún motivo, es posible que haya atracciones repetidas, pero solo es necesario ir una vez. El siguiente es el número m, que es el número del lugar escénico al que se dirige la niña.
Formato de salida
  Un número, el menor tiempo empleado.
Entrada de muestra
3
0 1 2 1
0 3
2 3 0
3
2 3 1
Salida de muestra
3
Tamaño de datos y convención
  0<n<=30, 0<m<=20, tiempo<=1000000

Respuesta:
Utilice el algoritmo de Floyd para encontrar primero el camino más corto y luego utilice dfs para recorrer el gráfico;

#include<iostream>
using namespace std;
const int N=32;
int dp[N][N],n,visit[N],des[N],m,num;//其中visit是在dfs中进行访问的数组,des是在main中访问节点的矩阵
int result=1e6;
void floyd(int (*a)[N],int n){
    
    
    for(int i = 1;i<=n;i++){
    
    
        for(int j = 1;j<=n;j++){
    
    
            for(int k =1;k<=n;k++){
    
    
                if(a[i][j]>a[i][k]+a[k][j])
                    a[i][j]=a[i][k]+a[k][j];
            }
        }
    }
}
void dfs(int cur, int cnt, int t) {
    
    
	if(cnt == num) {
    
    
		result = min(result, t);
		return;
	}
	for(int i=1; i<=n; i++) {
    
    
		if(des[i] && !visit[i] && dp[cur][i]+t <= result) {
    
    
			visit[i] = 1;
			dfs(i, cnt+1, t+dp[cur][i]);
			visit[i] = 0;
		}
	}
}

int main(){
    
    
    int a;
    cin >> n;
    for(int i = 1;i<=n;i++){
    
    
        for(int j = 1;j<=n;j++){
    
    
            cin >> dp[i][j];
        }
    }
    floyd(dp,n);
    cin >> m;
    for(int i = 1;i<=m;i++){
    
    
        cin >> a;
        if(!des[a]){
    
    
            des[a]=1;
            num++;
        }
    }
    for(int i =1;i<=n;i++){
    
    
        if(des[i]){
    
    
        for(int j =1;j<=n;j++)//这一步的操作是要把全部点置为0,因为原来我们从一个点开始遍历但是dfs算法无法把最开始的点置为零,因此每次dfs之前要置零
            visit[j]=0;
        visit[i]=1;
        dfs(i,1,0);
        }
    }
    cout<<result;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_47988292/article/details/129949296
Recomendado
Clasificación