心如止水
Je n'ai pas le temps
posts - 400,comments - 130,trackbacks - 0
先求任意两点之间不经过城堡的最短路。d[i][j]表示到达i点使用了j次鞋子的最短路长度。
以下是我的代码:
#include <queue>
#include 
<algorithm>
#include 
<cstdio>
#include 
<cstring>
using namespace std;

const int kMaxn = 107;
const int kMaxm = kMaxn * kMaxn;
const int kInf = 0x7f7f7f7f;

int A, B, M, L, K, g[kMaxn][kMaxn];
int d[kMaxn][17];
bool inq[kMaxn][17];

struct State {
    State ( 
const int &_u, const int &_k ) : u ( _u ), k ( _k ) { }
    
int u, k;
};

void Input () {
    memset ( g, 
0x7fsizeof ( g ) );
    scanf ( 
"%d%d%d%d%d"&A, &B, &M, &L, &K );
    
while ( M-- ) {
        
int u, v, w;
        scanf ( 
"%d%d%d"&u, &v, &w );
        g[u][v] 
= g[v][u] = w;
    }
}

void Solve () {
    
for ( int k = 1; k <= A; k++ )
        
for ( int i = 1; i <= A+B; i++ )
            
for ( int j = 1; j <= A+B; j++ )
                
if ( g[i][k] < kInf && g[k][j] < kInf && g[i][j] > g[i][k] + g[k][j] )
                    g[i][j] 
= g[i][k] + g[k][j];
    
    queue
<State> q;
    memset ( d, 
0x7fsizeof ( d ) );
    memset ( inq, 
falsesizeof ( inq ) );
    d[A
+B][0= 0;
    q.push ( State ( A
+B, 0 ) );
    
while ( !q.empty() ) {
        
int u = q.front().u, k = q.front().k;
        q.pop(); inq[u][k] 
= false;
        
for ( int v = 1; v <= A + B; v++ ) {
            
if ( k < K && g[u][v] <= L ) {
                
if ( d[v][k+1> d[u][k] ) {
                    d[v][k
+1= d[u][k];
                    
if ( !inq[v][k+1] ) {
                        q.push ( State ( v, k
+1 ) );
                        inq[v][k
+1= true;
                    }
                }
                
if ( d[v][k] > d[u][k] + g[u][v] ) {
                    d[v][k] 
= d[u][k] + g[u][v];
                    
if ( !inq[v][k] ) {
                        q.push ( State ( v, k ) );
                        inq[v][k] 
= true;
                    }
                }
            }
            
else {
                
if ( d[v][k] > d[u][k] + g[u][v] ) {
                    d[v][k] 
= d[u][k] + g[u][v];
                    
if ( !inq[v][k] ) {
                        q.push ( State ( v, k ) );
                        inq[v][k] 
= true;
                    }
                }
            }
        }
    }
    
int ans = kInf;
    
for ( int i = 0; i <= K; i++ )
        ans 
= min ( ans, d[1][i] );
    printf ( 
"%d\n", ans );
}

int main () {
#ifndef ONLINE_JUDGE
    freopen ( 
"data.in""r", stdin );
#endif
    
int T;
    scanf ( 
"%d"&T );
    
while ( T-- ) {
        Input ();
        Solve ();
    }
    
return 0;
}

posted on 2011-11-04 09:25 lee1r 阅读(963) 评论(0)  编辑 收藏 引用 所属分类: 题目分类:图论

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理