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;

}

 

你可能感兴趣的:(floyd)