Después de la codificación de tantos días, Sr. Acmer quiere tener una buena rest.So viajar es la mejor opción! Ha decidido visitar n ciudades (que insiste en ver todas las ciudades! Y que no le importa en qué ciudad siendo su estación de salida, porque Superman le puede aportar a cualquier ciudad en un primer momento, pero sólo una vez.), y por supuesto hay m carreteras aquí, siguiendo una cuota como usual.But Sr. Acmer se aburre con tanta facilidad que él no quiere visitar una ciudad más de dos veces ! Y él es tan mala que quiere minimizar el costo total! él es perezoso que see.So que se dirige a ti en busca de ayuda.
Entrada
Hay varios casos de prueba, la primera línea es de dos números enteros n (1 <= n <= 10) y m, lo que significa que tiene que visitar n ciudades y hay m caminos que puede elegir, entonces m líneas siguientes, cada línea incluyen tres números enteros a, b y c (1 <= a, b <= n), significa que hay un camino entre a y B y el coste es por supuesto c.Input al final del archivo.
Salida
Salida de la cuota mínima que debe pagar, o -1 si no puede encontrar una ruta tal.
Ejemplo de entrada
2 1
1 2 100
3 2
1 2 40
2 3 50
3 3
1 2 3
1 3 4
2 3 10
Ejemplo de salida
100
90
7
efecto tema: una persona ir a la gira de N de la ciudad, se puede partir de cualquier ciudad, hay m carretera entre las ciudades, el costo de cada camino tiene que hacer, resuelto a través de todas las ciudades, y cada ciudad visitada no más de dos veces el costo mínimo
Ideas: hemos estado en X número de ciudades, y el número de veces que un número X de ciudades son visitadas, y actualmente se encuentra en la ciudad como un estado, como punto de partida a la ciudad actual fue a otras ciudades para tratar de actualizar el estado de los costes mínimos correspondientes pero el número de estas ciudades han estado en este estado a cómo almacenarlo, abra una matriz n-dimensional es claramente poco realista, esta vez, pensamos que codifica la compresión se puede aplicar a otro:
En línea con el número de preguntas de cada ciudad sólo tres no han sido visitados, estado allí una vez, he estado allí dos veces, por lo que un número ternario se puede almacenar el estado de una ciudad, a continuación, n bits Tres sistema de números se puede almacenar el estado n ciudades, suponemos que el número ternario X, para la ciudad i bit i TRIT por lo tanto, el número de ciudades visitadas i es igual a X / (3 ^ i)% 3
Por lo tanto, podemos concluir fórmula recursiva:
Hombre para mí: dp [i] [j] = min (dp [i] [j], dp [i-3 ^ j] [v] + w [v] [j])
One for All: dp [i + 3 ^ v] = min (dp [i + 3 ^ v] [v], dp [i] [j] + w [j] [v])
Este problema se ha encontrado con un problema, olvidando la diferencia entre la función de llenado y MEMEST, memset se asigna byte a byte, empecé a usar INF = 999999, los resultados han conducido al error, por lo que si una cesión general por 1 y 0
Con el código:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define INF 0x3f
#define check(x,y) (x/tab[y])%3 //获取状态X中,到达Y城市的次数
using namespace std;
int tab[11]= {1},dp[60000][11]; //tab数组存储#3的次方数
int main() {
int n,m;
for(int i=1; i<=10; i++) { //初始化tab数组
tab[i]=tab[i-1]*3;
}
while(cin>>n>>m) {
int w[11][11],cost=0x3f3f3f3f;
memset(w,INF,sizeof(w));
memset(dp,INF,sizeof(dp)); //初始化为无穷大
int x,y,wi;
for(int i=0; i<m; i++) {
cin>>x>>y>>wi;
x--;
y--; //城市编号转化成 0开始
w[x][y]=w[y][x]=min(w[x][y],wi);
}
for(int i=0; i<n; i++)dp[tab[i]][i]=0; //初始化从每个城市出发的情况,保证每种状态都能遍历到
for(int i=1; i<tab[n]; i++) {
bool flag=true; //设置标志flag,如果 i 状态下,去过了 n个城市,则可以尝试更新最小花费
for(int j=0;j<n;j++){
if(check(i,j)==0){
flag=false; //i 状态下 j 城市没有去过
continue;
}
for(int v=0;v<n;v++){
if(check(i,v)==2)continue; //如果 i 状态下 v城市已经访问了两次跳过 v 城市
dp[i+tab[v]][v]=min(dp[i+tab[v]][v],dp[i][j]+w[j][v]); //我为人人递推
}
}
if(flag){ //0~n-1城市都有去过
for(int j=0;j<n;j++){
cost=min(cost,dp[i][j]); //尝试更新最小花费
}
}
}
if(cost==0x3f3f3f3f)cost=-1; //如果不能完成遍历所有城市的目标
cout<<cost<<endl;
// printf("%d\n",cost);
}
return 0;
}