hdu 4284 Travel floyd + 状压DP
http://acm.hdu.edu.cn/showproblem.php?pid=4284
题解:http://www.cnblogs.com/E-star/archive/2012/09/11/2680992.html
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> #include <string> #define CL(a,num) memset((a),(num),sizeof(a)) #define iabs(x) ((x) > 0 ? (x) : -(x)) #define Min(a,b) (a) > (b)? (b):(a) #define Max(a,b) (a) > (b)? (a):(b) #define ll long long #define inf 0x7f7f7f7f #define MOD 100000007 #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define test puts("<------------------->") #define maxn 100007 #define M 100007 #define N 107 using namespace std; //freopen("din.txt","r",stdin); struct node{ int c,d; int id; }p[N]; int n,m,moy,H; int mp[N][N],dp[1<<15][N]; void init(){ int i,j; for (i = 0; i <= n; ++i){ for (j = 0; j <= n; ++j){ mp[i][j] = (i != j)*inf; } } } void floyd(){ int i,j,k; for (k = 1; k <= n; ++k){ for (i = 1; i <= n; ++i){ for (j = 1; j <= n; ++j){ if (mp[i][k] != inf && mp[k][j] != inf && mp[i][j] > mp[i][k] + mp[k][j]){ mp[i][j] = mp[i][k] + mp[k][j]; } } } } } int main(){ //freopen("din.txt","r",stdin); int i,j,k,x,y,z; int t; scanf("%d",&t); while (t--){ scanf("%d%d%d",&n,&m,&moy); init(); for (i = 0; i < m; ++i){ scanf("%d%d%d",&x,&y,&z); if (mp[x][y] > z)//注意这里有重边 mp[x][y] = mp[y][x] = z; } floyd();//求出新距离 scanf("%d",&H); for (i = 0; i < H; ++i) scanf("%d%d%d",&p[i].id,&p[i].c,&p[i].d); CL(dp,-1); //初始化1可到达的点 for (i = 0; i < H; ++i){ int v = p[i].id; if (moy - mp[1][v] - p[i].d >= 0){ dp[1<<i][i] = moy - mp[1][v] - p[i].d + p[i].c; } } for (i = 1; i <= ((1<<H) - 1); ++i){ for (j = 0; j < H; ++j){ if (dp[i][j] == -1) continue;//对于以j结尾的i路线存在 int u = p[j].id; for (k = 0; k < H; ++k){//查看j是否可到k if ((i&(1<<k)) == 0){ int v = p[k].id; if (dp[i][j] - mp[u][v] - p[k].d >= 0){//可到 int now = (i^(1<<k)); if (dp[now][k] == -1 || dp[now][k] < dp[i][j] - mp[u][v] - p[k].d + p[k].c) dp[now][k] = dp[i][j] - mp[u][v] - p[k].d + p[k].c; } } } } } bool flag = false ; for (i = 0; i < H; ++i){ if (dp[((1<<H) - 1)][i] - mp[p[i].id][1] >= 0){ flag = true; break; } } if (flag) printf("YES\n"); else printf("NO\n"); } return 0; }