题意:有N个城市M条路相连,有两种收费方式,一种是在城市Ci时收费为Pi,另一种是在城市Bi中Ri,求从城市1到城市N的最小花费。其中Pi要小于Ri。
思路:其实我觉得这就是一道变形的最短路问题,虽然是用的深搜,但原理是一样的。首先将于城市Ai相连的城市都存起来,然后用一个数组记录城市I是否被访问过,如果访问过,当然可以直接在城市I缴费,原以为每个点访问一次就行了,可是后来想一想,不是这样的,要是这样的就没法提前在Ci城市缴费了,后来在网上看到有人是“闸数”,也就是一个点最多不会被访问超过3次,否则就退出,然后就按这个方法来做的~
代码:
View Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> #include <math.h> #define N 14 #define INF 100000000 using namespace std ; struct point { int b , c ; int p , r ; int next ; }d[N] ; int head[N] , vis[N] ; int n , m , ans ; void dfs( int x , int s ) { //结束条件 if ( s > ans ) { return ; } if ( x == n ) { ans = s ; return ; } for ( int i = head[x] ; i != -1 ; i = d[i].next ) { int v = d[i].b ; if( vis[v] <= 3 ) { vis[v]++ ; if ( vis[d[i].c] > 0 ) dfs( v , s + d[i].p ); else dfs( v , s + d[i].r ); vis[v]-- ; } } } int main() { int i , j , k , x ; scanf( "%d%d" , &n , &m ) ; memset( head , -1 , sizeof( head )); memset( vis , 0 , sizeof ( vis )); //用邻接表存储 for ( i = 1 ; i <= m ; i++ ) { scanf( "%d%d%d%d%d" , &x , &d[i].b , &d[i].c , &d[i].p , &d[i].r ); d[i].next = head[x] ; head[x] = i ; } vis[1] = 1 ; ans = INF ; dfs( 1 , 0 ); if ( ans == INF ) printf( "impossible\n" ); else printf ( "%d\n" , ans ); return 0 ; }