zoukankan      html  css  js  c++  java
  • poj 3411 Paid Roads

    题意:

    n个城市,m条双向路径。

    从a城市到b城市,有两种付费方法:

    1.在c城市预先付费,前提是已经到达了c城市;

    2.到了b城市之后,在b付费。

    给出路径以及付费信息,求出从1到n的最少花费,或判断从1无法到达n。

    思路:

    状态压缩dp,每次更新的时候,更新两次,第一次更新未到达的城市,第二次更新可以通过中转城市话费更少到达的城市。

    转移方程:

    dp[S|(1<<k)][k] = min(dp[S|(1<<k)][k] ,dp[S][j] + cost[j][k]),其中cost[j][k]要么是提前,要么是到付,判断一下条件即可。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <vector>
     5 using namespace std;
     6 const int inf = 0x3f3f3f3f;
     7 const int N = 12;
     8 int dp[(1<<N)][N];
     9 struct node
    10 {
    11     int a,b,c,p,r;
    12     node(int aa,int bb,int cc,int pp,int rr)
    13     {
    14         a = aa;
    15         b = bb;
    16         c = cc;
    17         p = pp;
    18         r = rr;
    19     }
    20     node(){};
    21 };
    22 vector<node> g[N];
    23 int main()
    24 {
    25     int n,m;
    26     while (scanf("%d%d",&n,&m)!=EOF)
    27     {
    28         memset(dp,inf,sizeof(dp));
    29         for (int i = 0;i < n;i++) g[i].clear();
    30         for (int i = 0;i < m;i++)
    31         {
    32             int a,b,c,p,r;
    33             scanf("%d%d%d%d%d",&a,&b,&c,&p,&r);
    34             a--,b--,c--;
    35             g[a].push_back(node(a,b,c,p,r));
    36         }
    37         dp[1][0] = 0;
    38         for (int i = 0;i < (1<<n);i++)
    39         {
    40             for (int j = 0;j < n;j++)//第一次
    41             {     
    42                 if (!(i&(1<<j))) continue;
    43                 for (int k = 0;k < g[j].size();k++)
    44                 {
    45                     int to = g[j][k].b;
    46                     int c = g[j][k].c;
    47                     dp[i|(1<<to)][to] = min(dp[i|(1<<to)][to],dp[i][j] + g[j][k].r);
    48                     if (i&(1<<c)) dp[i|(1<<to)][to] = min(dp[i|(1<<to)][to],dp[i][j] + g[j][k].p);
    49                 }
    50             }
    51             for (int j = 0;j < n;j++)//第二次
    52             {     
    53                 if (!(i&(1<<j))) continue;
    54                 for (int k = 0;k < g[j].size();k++)
    55                 {
    56                     int to = g[j][k].b;
    57                     int c = g[j][k].c;
    58                     dp[i|(1<<to)][to] = min(dp[i|(1<<to)][to],dp[i][j] + g[j][k].r);
    59                     if (i&(1<<c)) dp[i|(1<<to)][to] = min(dp[i|(1<<to)][to],dp[i][j] + g[j][k].p);
    60                 }
    61             }
    62         }
    63         int ans = inf;
    64         for (int i = 0;i <(1<<n);i++) ans = min(ans,dp[i][n-1]);
    65         if (ans >= inf) puts("impossible");
    66         else printf("%d
    ",ans);
    67     }
    68     return 0;
  • 相关阅读:
    华为靠近获准为伦敦地铁供给移动收集
    Solaris 10装置jdk1.6及改削成默许JDK
    “沃Phone”生于忧患 联通推另类新规
    Android 3.0终极版SDK正式颁发颁发
    MyGeneration连接MySql数据库的处理步履
    解析:百思买败于外部派系争斗
    联发科月度付出跌至四年来冰点
    AT&T:iPhone带来无线营业量收齐打破
    阐发师以为移动网络运营商需斥地数据获利新途径
    MSSQL按分页前去查询成绩的存储历程
  • 原文地址:https://www.cnblogs.com/kickit/p/8866472.html
Copyright © 2011-2022 走看看