题目链接

问题分析

比较明显的最短路模型。需要堆优化的dij。建图的时候注意细节就好。

参考程序

#include <bits/stdc++.h>
#define LL long long
//#define DEBUG
using namespace std; const int Maxn = 10010;
const int Maxm = 100010;
const int Maxk = 12;
struct edge {
int To, Next, Cost;
};
edge Edge[ Maxm << 1 ];
int Start[ Maxn ], Used;
int n, m, k, Tag[ Maxn ], Dis[ Maxn ][ Maxk << 1 ], s, t, Vis[ Maxn ][ Maxk << 1 ];
int DistK;
struct heap {
int Used, Tree[ Maxn * ( Maxk << 1 ) ], Ref[ Maxn * ( Maxk << 1 ) ];
void Clear() { Used = 0; return; }
bool Cmp( int x, int y ) {
return Dis[ x / DistK ][ x % DistK ] < Dis[ y / DistK ][ y % DistK ];
}
bool Empty() { return Used == 0; }
inline void Swap( int x, int y ) {
Ref[ Tree[ x ] ] = y;
Ref[ Tree[ y ] ] = x;
swap( Tree[ x ], Tree[ y ] );
return;
}
void Insert( int x ) {
++Used; Tree[ Used ] = x; Ref[ x ] = Used;
int Temp = Used;
for( ; Temp > 1; )
if( Cmp( Tree[ Temp ], Tree[ Temp >> 1 ] ) )
Swap( Temp, Temp >> 1 ), Temp >>= 1;
else
break;
return;
}
void Fresh( int x ) {
int Temp = Ref[ x ];
for( ; Temp > 1; )
if( Cmp( Tree[ Temp ], Tree[ Temp >> 1 ] ) )
Swap( Temp, Temp >> 1 ), Temp >>= 1;
else
break;
return;
}
int Top() { return Tree[ 1 ]; }
void Pop() {
Swap( 1, Used ); --Used;
int Temp = 1;
for( ; ( Temp << 1 ) <= Used; ) {
if( ( Temp << 1 | 1 ) > Used ) {
if( Cmp( Tree[ Temp << 1 ], Tree[ Temp ] ) )
Swap( Temp, Temp << 1 );
break;
}
if( Cmp( Tree[ Temp << 1 ], Tree[ Temp << 1 | 1 ] ) )
if( Cmp( Tree[ Temp << 1 ], Tree[ Temp ] ) ) {
Swap( Temp, Temp << 1 );
Temp <<= 1;
}
else
break;
else
if( Cmp( Tree[ Temp << 1 | 1 ], Tree[ Temp ] ) ) {
Swap( Temp, Temp << 1 | 1 );
Temp = Temp << 1 | 1;
}
else
break;
}
return;
}
};
heap Heap; void Clear() {
memset( Start, 0, sizeof( Start ) );
Used = 0;
memset( Dis, 255, sizeof( Dis ) );
Heap.Clear();
return;
} inline void AddEdge( int x, int y, int z ) {
Edge[ ++Used ] = ( edge ){ y, Start[ x ], z };
#ifdef DEBUG
printf( "AddEdge %d -> %d : %d\n", x, y, z );
#endif
Start[ x ] = Used;
return;
} void Init() {
scanf( "%d%d%d", &n, &m, &k );
++k;
for( int i = 1; i <= n; ++i ) scanf( "%d", &Tag[ i ] );
for( int i = 1; i <= n; ++i ) Tag[ i ] = ( Tag[ i ] == 1 ) ? -1 : 1;
for( int i = 1; i <= m; ++i ) {
int x, y, z; scanf( "%d%d%d", &x, &y, &z );
AddEdge( x, y, z ); AddEdge( y, x, z );
}
scanf( "%d%d", &s, &t );
DistK = k << 1;
return;
} void Work() {
Clear();
Init();
Dis[ s ][ k + Tag[ s ] ] = 0;
if( k + Tag[ s ] < 1 || k + Tag[ s ] >= DistK ) {
printf( "-1\n" );
return;
}
Heap.Insert( s * DistK + k + Tag[ s ] );
Vis[ s ][ k ] = 2;
for( ; !Heap.Empty(); ) {
int T = Heap.Top();
Heap.Pop();
int u = T / DistK;
Vis[ u ][ T % DistK ] = 1;
#ifdef DEBUG
printf( "Sol %d %d %d\n", u, T % DistK, Dis[ u ][ T % DistK ] );
#endif
for( int t = Start[ u ]; t; t = Edge[ t ].Next ) {
int v = Edge[ t ].To; int p = T % DistK + Tag[ v ];
if( p < 1 || p >= DistK ) continue;
if( Vis[ v ][ p ] == 1 ) continue;
if( Dis[ v ][ p ] == -1 ||
Dis[ v ][ p ] > Dis[ u ][ T % DistK ] + Edge[ t ].Cost ) {
Dis[ v ][ p ] = Dis[ u ][ T % DistK ] + Edge[ t ].Cost;
#ifdef DEBUG
printf( " Cha %d %d %d\n", v, p, Dis[ v ][ p ] );
#endif
if( Vis[ v ][ p ] == 2 ) Heap.Fresh( v * DistK + p );
else {
Heap.Insert( v * DistK + p );
Vis[ v ][ p ] = 2;
}
}
}
}
int Ans = -1;
for( int i = 1; i < DistK; ++i )
if( Dis[ t ][ i ] != -1 && ( Ans == -1 || Ans > Dis[ t ][ i ] ) )
Ans = Dis[ t ][ i ];
printf( "%d\n", Ans );
return;
} int main() {
int TestCases; scanf( "%d", &TestCases );
for( ; TestCases--; ) Work();
return 0;
}

最新文章

  1. hyper-v上的虚拟机安装linux LC后CDROM无法使用
  2. java Thumbnails 加载网络图片,处理返回base64
  3. Programming Assignment 5: Kd-Trees
  4. [C++][语言语法]标准C++中的string类的用法总结
  5. activiti 学习( 三 ) 之 流程启动者
  6. linux 信号列表和基本作用
  7. PCL—低层次视觉—关键点检测(rangeImage)
  8. 跨域请求CORS
  9. 空间搜索(圆范围)中Geohash编码方案和网格编码方案对比探讨
  10. Android Studio 2.0 Preview 4 的逆袭以及各种神注释
  11. 网易面经(Java开发岗)
  12. 配置babel
  13. canvas-a13prototype.html
  14. 彻底搞懂 CPU 中的内存结构
  15. NABCD框架(作业和事件的定期提醒)及第八周学习进度条
  16. logstash启动脚本
  17. leetcode-166-分数到小数(用余数判断有没有出现小数的循环体)
  18. ORACLE 导出表结构及备注
  19. Read N Characters Given Read4
  20. 利用 TestNG 并行执行用例

热门文章

  1. Java第七周课堂示例总结
  2. Anaconda中安装pytorch
  3. HDU-5238 Calculator
  4. Dango之视图函数
  5. 一些通用的js工具类,添加自定义插件
  6. django自带登录认证与登录自动跳转
  7. Uncaught SyntaxError: Unexpected identifier
  8. Vue路由守卫之路由独享守卫
  9. int 问号的使用
  10. Linux Exploit系列之二 整数溢出