hdu 4284 Travel (2012 天津网络赛 1007 )
2012-09-10 16:00
381 查看
这题当场没有做出来, 看了芳姐代码后面还弄出了个超时
,spfa 加位压缩的bfs过的;
先spfa算出目标点两两之间的最短距离;
bfs搜的是dp[i][j]; 当前所在点为i, 状态是j, 2进制j的第x位为1表示第x个目标点已经购买过了通行证;
复杂度O(15*(2^15))+O(15*15*spfa());险过
,spfa 加位压缩的bfs过的;
先spfa算出目标点两两之间的最短距离;
bfs搜的是dp[i][j]; 当前所在点为i, 状态是j, 2进制j的第x位为1表示第x个目标点已经购买过了通行证;
复杂度O(15*(2^15))+O(15*15*spfa());险过
#include<cstdio> #include<cstring> #include<queue> #define maxn 113 #define maxm 11005 using namespace std; int vv[maxm], nxt[maxm], ww[maxm], h[maxn], e; int d[maxn], svis[maxn]; void link( int u, int v, int c ) { vv[e] = v; ww[e] = c; nxt[e] = h[u]; h[u] = e++; } void spfa( int s ) { memset( svis, 0, sizeof(svis) ); memset( d, -1, sizeof(d) ); d[s] = 0; queue<int>q; q.push( s ); while( !q.empty() ){ int u = q.front(); q.pop(); svis[u] = 0; for( int j = h[u]; j+1; j = nxt[j] ){ int v = vv[j]; if( d[v] == -1 || d[v] > d[u] + ww[j] ){ d[v] = d[u] + ww[j]; if( !svis[v] ) svis[v] = 1, q.push( v ); } } } } int C[20], D[20], dd[20][20]; int dp[20][70000], vis[20][70000]; int num[20], H, S; int bit[20], n, m, money; int bfs(int is) { for( int i = 1; i <= H; i++ ){ memset( dp[i], -1, sizeof(int)*(bit[H+1]+5) ); memset( vis[i], 0, sizeof(int)*(bit[H+1]+5) ); } //memset(dp, -1, sizeof(dp)); //memset(vis, 0, sizeof(vis)); queue<int> q; if(is){ q.push(70000*S); dp[S][0] = money; vis[S][0] = 1; } else{ for( int i = 1; i <= H; i++ ){ if( dd[S][i] >= 0 && money >= dd[S][i] + D[i] ){ dp[i][bit[i]] = money - dd[S][i] - D[i] + C[i]; q.push( i * 70000 + bit[i] ); vis[i][bit[i]] = 1; } } } while( !q.empty() ){ int u = q.front(); q.pop(); int st = u / 70000, state = u % 70000; vis[st][state] = 0; if( dp[st][state] < 0 ) continue; for( int i = 1; i <= H; i++ ){ if( dp[st][state] - dd[st][i] - D[i] < 0 ) continue; if( (state&bit[i]) == 0 && dd[st][i] >= 0 ){ int stv = state | bit[i]; if( dp[i][stv] < dp[st][state] - dd[st][i] - D[i] + C[i] ){ dp[i][stv] = dp[st][state] - dd[st][i] - D[i] + C[i]; int v = i*70000 + stv; if( !vis[i][stv] ) vis[i][stv] = 1, q.push( v ); } } } } for( int i = 1; i <= H; i++ ) if( dd[i][S] >= 0 && dp[i][bit[H+1]-1] - dd[i][S] >= 0 ) return 1; return 0; } int main() { bit[1] = 1; for( int i = 2; i <= 18; i++ ) bit[i] = bit[i-1]<<1; int T; int a, b, c; scanf( "%d", &T ); while( T-- ){ scanf( "%d%d%d", &n, &m, &money ); e = 0; memset( h, -1, sizeof(h) ); for( int i = 0; i < m; i++ ){ scanf( "%d%d%d", &a, &b, &c ); link( a, b, c ); link( b, a, c ); } scanf( "%d", &H ); S = 0; for( int i = 1; i <= H; i++ ){ scanf( "%d%d%d", &num[i], &C[i], &D[i] ); if( num[i] == 1 ) S = i; } int s = S; if( !S ){ num[++H] = 1; C[H] = 0; D[H] = 0; S = H; } for( int i = 1; i <= H; i++ ){ spfa( num[i] ); for( int j = 1; j <= H; j++ ) dd[i][j] = d[num[j]]; } if( !s ) H--; // 这一步非常重要, 它把最大复杂度O(2^16)降为O(2^15),这个跑了3s, 乘2就超时了; if( bfs(s) ) printf( "YES\n" ); else printf( "NO\n" ); } }
相关文章推荐
- hdu 4284 Travel 2012天津网络赛 状压dp TSP 最短路
- hdu 4279 Number 2012天津网络赛 数论 分析
- HDU 4284 Travel(12年天津 状态DP)
- hdu 4278 2012天津赛区网络赛 数学 *
- HDU 4279 Number(2012天津网络游戏---数论分析题)
- 2012天津赛区网络赛 hdu 4280 Island Transport
- HDU 4284 Travel(12年天津online floyd + tsp状态DP)
- hdu 4282 A very hard mathematic problem (2012 天津网络赛 1005)
- hdu 4278 Faulty Odometer 2012 天津网络赛 数位dp
- HDU - 4284 Travel(状压dp)
- HDU 4284 Travel(状压dp)
- hdu 4417 2012杭州网络赛 划分树
- hdu 5838 Mountain(2016 CCPC网络赛1007) 状压
- hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***
- hdu 4284 Travel(floyd + TSP)
- HDU 4284 Travel
- HDU 4284 —— Travel 状压dp|DFS+Floyd
- HDU 4279 Number 第37届ACM/ICPC天津赛区网络赛1002题 (简单规律题)
- HDU 4284 Travel【状态压缩DP】
- HDU 5441 Travel (2015ACM/iCPC长春网络赛E )