题意:给定一些点,这些点本身有价值,并且可以同过某些点转化到自身。
对于lev问题,可以进行枚举出每个点的lev,看哪些点与当前被枚举点是可以相互到达的。这样就解决了点点之间是否可以相互到达问题。
对于路的权值问题,可以稍微进行转化,在更新dis的时候可以明白。dis[ j ] = min( dis[ j ],dis[ k ]+mat[ k ][ j ] ); //mat[ k ][ j ]:表示k到j的路径花费值
1 /* 2 dijkstra 3 */ 4 #include<stdio.h> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<algorithm> 8 #include<iostream> 9 #include<queue> 10 #include<map> 11 #include<math.h> 12 using namespace std; 13 typedef long long ll; 14 //typedef __int64 int64; 15 const int maxn = 105; 16 const int inf = 99999999; 17 const double pi=acos(-1.0); 18 const double eps = 1e-8; 19 20 int mat[ maxn ][ maxn ]; 21 int dis[ maxn ],vis[ maxn ]; 22 struct node{ 23 int lev,price,cnt; 24 int ex_num[ maxn ],ex_pay[ maxn ]; 25 }tra[ maxn ]; 26 27 void dijkstra( int n ){ 28 for( int i=1;i<=n;i++ ){ 29 dis[ i ] = tra[ i ].price; 30 } 31 for( int i=1;i<=n;i++ ){ 32 int m,k; 33 m = inf,k = -1; 34 for( int j=1;j<=n;j++ ){ 35 if( vis[ j ]==0&&m>dis[ j ] ){ 36 m = dis[ j ]; 37 k = j; 38 } 39 } 40 if( k==-1 ) return ; 41 vis[ k ] = 1; 42 for( int j=1;j<=n;j++ ){ 43 if( vis[ j ]==0&&mat[k][j]>0 ){ 44 dis[ j ] = min( dis[ j ],dis[ k ]+mat[ k ][ j ] ); 45 } 46 } 47 } 48 } 49 50 int main(){ 51 int m,n; 52 while( scanf("%d%d",&m,&n)==2 ){ 53 memset( mat,0,sizeof( mat ) ); 54 for( int i=1;i<=n;i++ ){ 55 scanf("%d%d%d",&tra[ i ].price,&tra[ i ].lev,&tra[ i ].cnt); 56 for( int j=0;j<tra[i].cnt;j++ ){ 57 scanf("%d%d",&tra[ i ].ex_num[ j ],&tra[ i ].ex_pay[ j ]); 58 mat[ tra[i].ex_num[j] ][ i ] = tra[ i ].ex_pay[ j ]; 59 } 60 } 61 int res = inf; 62 for( int i=1;i<=n;i++ ){ 63 for( int j=1;j<=n;j++ ){ 64 if( tra[ j ].lev>tra[ i ].lev||(tra[i].lev-tra[j].lev)>m ) 65 vis[ j ] = 1; 66 else 67 vis[ j ] = 0; 68 } 69 dijkstra( n ); 70 res = min( res,dis[1] ); 71 } 72 printf("%d\n",res); 73 } 74 return 0; 75 } 76