• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
james1207

博客园    首页    新随笔    联系   管理    订阅  订阅

POJ 2686 Traveling by Stagecoach 壮压DP


大意是有一个人从某个城市要到另一个城市(点数<=30)

然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票。

花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间。

问最后这个人花费的最短时间是多少


然后就是壮压DP了

dp[S][v] 代表当前消耗了S集合的车票走到v花费的最小时间

可以用spfa转移。

也可以直接转移。

直接转的原因是,这个图由于走路要消耗车票,所以实质上图是个DAG


看两种代码


 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#define MAXN 2222
#define INF 1000000007
using namespace std;
double dp[333][33];
typedef pair<int, int> P;
vector<P>g[33];
int t, n, m, src, des;
int num[33];
int main ()
{
    int u, v, w;
    while(scanf("%d%d%d%d%d", &t, &n, &m, &src, &des) != EOF)
    {
        if(!t && !n && !m && !src && !des) break;
        for(int i = 0; i < t; i++) scanf("%d", &num[i]);
        for(int i = 0; i <= n; i++) g[i].clear();
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            g[u].push_back(make_pair(v, w));
            g[v].push_back(make_pair(u, w));
        }
        for(int i = 0; i <= 300; i++)
            for(int j = 0; j < 33; j++)
                dp[i][j] = INF;
        dp[0][src] = 0;
        double res = INF;
        for(int i = 0; i < (1 << t); i++)
        {
            for(u = 1; u <= n; u++)
                 for(int k = 0; k < t; k++)
                    if(!(i & (1 << k)))
                    {
                        for(int j = 0; j < g[u].size(); j++)
                        {
                            v = g[u][j].first;
                            w = g[u][j].second;
                            dp[i | (1 << k)][v] = min(dp[i | (1 << k)][v], dp[i][u] + (double)w / num[k]);
                        }
                    }
            res = min(res, dp[i][des]);
        }
        if(res == INF) puts("Impossible");
        else printf("%.3f\n", res);

    }
    return 0;
}


然后是SPFA

 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define MAXN 2222
#define INF 1000000007
using namespace std;
double dp[333][33];
typedef pair<int, int> P;
vector<P>g[33];
int t, n, m, src, des;
int num[33], vis[333][33];
queue<P>q;
void spfa()
{
    for(int i = 0; i <= 300; i++)
        for(int j = 0; j < 33; j++)
            dp[i][j] = INF;
    memset(vis, 0, sizeof(vis));
    dp[0][src] = 0;
    vis[0][src] = 1;
    while(!q.empty()) q.pop();
    q.push(make_pair(0, src));
    while(!q.empty())
    {
        P top = q.front();
        q.pop();
        int S = top.first;
        int u = top.second;
        for(int j = 0; j < t; j++)
        {
            if(S & (1 << j)) continue;
            for(int i = 0; i < g[u].size(); i++)
            {
                int v = g[u][i].first;
                int w = g[u][i].second;
                if(dp[S | (1 << j)][v] > dp[S][u] + (double)w / num[j])
                {
                    dp[S | (1 << j)][v] = dp[S][u] + (double)w / num[j];
                    if(!vis[S | (1 << j)][v])
                    {
                        q.push(make_pair(S | (1 << j), v));
                        vis[S | (1 << j)][v] = 1;
                    }
                }
            }
        }
    }
    double res = INF;
    for(int i = 0; i < (1 << t); i++)
        res = min(res, dp[i][des]);
    if(res == INF) puts("Impossible");
    else printf("%.3f\n", res);
}
int main ()
{
    int u, v, w;
    while(scanf("%d%d%d%d%d", &t, &n, &m, &src, &des) != EOF)
    {
        if(!t && !n && !m && !src && !des) break;
        for(int i = 0; i < t; i++) scanf("%d", &num[i]);
        for(int i = 0; i <= n; i++) g[i].clear();
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            g[u].push_back(make_pair(v, w));
            g[v].push_back(make_pair(u, w));
        }
        spfa();
    }
    return 0;
}


 

 

posted @ 2013-09-16 18:56  Class Xman  阅读(129)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3