zoukankan      html  css  js  c++  java
  • hdu 4284 Travel(壮压DP&TSP&floyd)

    Travel

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2621    Accepted Submission(s): 720

    Problem Description
    PP loves travel. Her dream is to travel around country A which consists of N cities and M roads connecting them. PP has measured the money each road costs. But she still has one more problem: she doesn't have enough money. So she must work during her travel. She has chosen some cities that she must visit and stay to work. In City_i she can do some work to earn Ci money, but before that she has to pay Di money to get the work license. She can't work in that city if she doesn't get the license but she can go through the city without license. In each chosen city, PP can only earn money and get license once. In other cities, she will not earn or pay money so that you can consider Ci=Di=0. Please help her make a plan to visit all chosen cities and get license in all of them under all rules above.
    PP lives in city 1, and she will start her journey from city 1. and end her journey at city 1 too.
     
    Input
    The first line of input consists of one integer T which means T cases will follow.
    Then follows T cases, each of which begins with three integers: the number of cities N (N <= 100) , number of roads M (M <= 5000) and her initiative money Money (Money <= 10^5) .
    Then follows M lines. Each contains three integers u, v, w, which means there is a road between city u and city v and the cost is w. u and v are between 1 and N (inclusive), w <= 10^5.
    Then follows a integer H (H <= 15) , which is the number of chosen cities.
    Then follows H lines. Each contains three integers Num, Ci, Di, which means the i_th chosen city number and Ci, Di described above.(Ci, Di <= 10^5)
     
    Output
    If PP can visit all chosen cities and get all licenses, output "YES", otherwise output "NO".
     
    Sample Input
    2 4 5 10 1 2 1 2 3 2 1 3 2 1 4 1 3 4 2 3 1 8 5 2 5 2 3 10 1 2 1 100 1 2 10000 1 2 100000 1
     
    Sample Output
    YES NO
     
    Source
     
    Recommend
    liuyiding   |   We have carefully selected several similar problems for you:   4268  4269  4270  4271  4272 
     

    题意:

    一个人要去旅游。给你n个城市和m条道路。其中有h个城市必须在那里打工。打工的话必须办证。办证要花掉d[i]的钱币。但是有c[i]的工资。每条道路都需花费一定的钱币。告诉你他的初始钱币数。问他能否将这h个城市都工作完。

    思路:

    y由于h的范围比较小。可以状态压缩。考虑经过的情况直接可以用floyd求出两个城市间的最小花费。然后就是典型的TSP了。

    详细见代码:

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    const int INF=0x3f3f3f3f;
    using namespace std;
    int dp[105][1<<16];
    int dis[105][105];
    int C[150],D[150],id[150];
    int n,m,h,mon;
    void floyd()
    {
        for (int k=1;k<=n;k++)
            for (int i=1;i<=n;i++)
                for (int j=1;j<=n;j++)
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    }
    int main()
    {
        int t,i,j,u,v,w,lim,ns,s,ans;
        scanf("%d",&t);
        while (t--)
        {
            memset(dis,0x3f,sizeof dis);
            scanf("%d%d%d",&n,&m,&mon);
            for(i=0;i<m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                dis[u][v]=dis[v][u]=min(dis[u][v],w);//习惯性的就判重了。据说这题还真有重边
            }
            for(i=1;i<=n;i++)
                dis[i][i]=0;
            floyd();
            scanf("%d",&h);
            for(i=1;i<=h;i++)
                scanf("%d%d%d",&id[i],&C[i],&D[i]);//异常2B。开始后面把id[i]和i混为一谈了
            memset(dp,0xcf,sizeof dp);
            dp[1][0]=mon;
            for(i=1;i<=h;i++)
            {
                v=id[i];
                if(dp[1][0]>=D[i]+dis[1][v])
                {
                    ns=1<<(i-1);
                    dp[v][ns]=dp[1][0]-D[i]-dis[1][v]+C[i];//只有距离才用还原到原标号
                }
            }
            lim=1<<h;
            for(s=0;s<lim;s++)
            {
                for(i=1;i<=h;i++)//开始2B了。套了两个n果断超时了。
                {
                    u=id[i];//其实直接考虑必须工作的城市就行了.因为最后还是会到必须到的城市
                    if(dp[u][s]<0||!(s&(1<<(i-1))))//保证状态有效
                        continue;
                    for(j=1;j<=h;j++)
                    {
                        v=id[j];
                        if(!(s&(1<<(j-1))))
                        {
                            ns=s|(1<<(j-1));
                            if(dp[u][s]>=D[j]+dis[u][v])
                                dp[v][ns]=max(dp[v][ns],dp[u][s]-D[j]-dis[u][v]+C[j]);
                        }
                    }
                }
            }
            ans=-INF;
            for(i=1;i<=h;i++)
            {
                u=id[i];
                ans=max(ans,dp[u][lim-1]-dis[u][1]);
            }
            if(ans>=0)
                printf("YES
    ");
            else
                printf("NO
    ");
        }
        return 0;
    }
    



  • 相关阅读:
    zabbix4.2.5常见问题指南
    postgres常用运维sql
    centos7部署inotify与rsync实现实时数据同步
    postgres主从基于流复制
    postgres高可用学习篇三:haproxy+keepalived实现postgres负载均衡
    postgres高可用学习篇二:通过pgbouncer连接池工具来管理postgres连接
    postgres高可用学习篇一:如何通过patroni如何管理3个postgres节点
    centos7安装yum安装pip
    nginx1.15.10配置使用非https访问返回403
    zabbix4.2.5自定义告警模板
  • 原文地址:https://www.cnblogs.com/riskyer/p/3395466.html
Copyright © 2011-2022 走看看