达内杯--H 技术员BangFu 

 这题的确是一道好题,很好的将状态dp以及图论的最短路径,这里上面的权值表示的花费的钱,另外还有很多约束问题,

 首先大体描述下这道题,就是一个技术员,遍历N个节点,首先他一开始在0号节点,且是星期一,然后遍历1..N-1 编号的节点,这里要求每个节点只能走一次,而且必须每个节点都得走到,最后还要回到0号节点,而且从一个定点到另一个顶点是要花费p天的时间,还要要一定的钱,而且在每个节点也至少得待一天的时间,最后的最后,要我们解决的问题是,首先判定他是否能够每个节点都能走到,另外,如果能又是否能在星期六或星期天到,若是,那么我们至少得花多少钱呢!

  问题已经很清晰了,现在的问题就是如何求了,按照我开始的思路,首先判定这是否是一个遍历所有节点的回路,然后既然这是一个状态dp的问题,那么肯定是涉及到状态的改变的,那么状态是什么呢,这里就是走过的节点,可以作为状态,如果已经走过,那么为1,否则为0,那么N个节点可以表示成一个二进制串,然后相对应的十进制值就是状态数,如上,我们如何判断状态的合法性,这里就是走过的节点就不要回去了,所以就很好判断了,也就是说每一位只能置1一次,好,搞过之后,我们在找状态方程,因为这里好像很隐藏,

因为问题描述当中,有要求的天数,和花费的钱数,那么这个方程到底怎么表示呢!

 这里设dp[state][des][d]  这个方程的意思就是状态为state时,且到达了des节点,且此时是星期,另外这个值就是达到这点所花费的钱   0<=state<2^N,1<=des<=N-1,0<=d<7

   然后就是初始化问题,dp[0][0][0]=inf,dp[1][0][0]=0,然后就是用bfs遍历找出求最短路劲了,这里最短路劲也好求,首先在输入的时候,建立邻接表,bfs的用队列维护,这里就如上所述,所涉及的要保存的信息很多,于是我们想到结构体,用结构体来表示节点以及边,这样,这个过程就很好办了,当然我们知道bfs的过程中,还有一个visit的,这里也需要建立类似的标记,这里要和dp有同样的大小,

 这样搞过之后,最后就很好办了,首先dp[2^N-1][1....N][D] ,循环遍历在目标1....N个节点中看看有没到0号节点的,两个fou循环,找出最小值,同时判断是否能够在星期六和星期天道,这些都很好办了,,接下来就可以去是实现了,,就是苦力活了,,有许多的细节,要考虑全面!

  

   下面的代码就是写给自己看的,成功AC!
    

View Code