poj 2686 最短路

#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;
}

https://blog.csdn.net/sdj222555/article/details/11739205

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#define MX 0x3f3f3f3f
using namespace std;
typedef long long LL;
int t,n,m,sr,de,fa[35];
double dp[1<<8][35];
int d[35][35],ti[35],vis[1<<8][35];
vector<int> g[35];
pair<int,int> P;
queue<pair<int,int> > q;
void spfa()
{
    //...
    for(int i=0;i<=(1<<n)-1;i++)
        for(int j=1;j<=n;j++)
            dp[i][j]=MX*1.0;
    memset(vis,0,sizeof vis);
    dp[0][sr]=0.0;
    vis[0][sr]=1;   //
    q.push(make_pair(0,sr));
    while(!q.empty())
    {
        pair<int,int> tp;
        tp=q.front();q.pop();
        int s=tp.first;
        int u=tp.second;
        cout<<"s,u:"<<s<<","<<u<<endl;///
        for(int i=0;i<g[u].size();i++)
        {
            int v=g[u][i];
            if(v==fa[u])continue;
            fa[v]=u;
            cout<<"v:"<<v<<endl;///
            for(int j=0;j<t;j++)
            {
                if(s & (1 << j)) continue;
                if(dp[s|1<<j][v] > dp[s][u] + double(d[u][v])/double(ti[j]))
                {
                    cout<<"dp:"<<dp[s|1<<j][v]<<","<<dp[s][u]+double(d[u][v])/double(ti[j])<<endl;
                    dp[s|1<<j][v]=dp[s][u]+double(d[u][v])/double(ti[j]);   
                    if(!vis[s|1<<j][v])
                    {
                        q.push(make_pair(s|1<<j,v));
                        vis[s|1<<j][v]=1;//
                    }
                }
            }
        }
    }
} 
int x,y,w;
int main()
{
    scanf("%d%d%d%d%d",&t,&n,&m,&sr,&de);
    for(int i=0;i<t;i++)
        scanf("%d",&ti[i]);//车票 
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&w);
        g[x].push_back(y);
        g[y].push_back(x);
        d[x][y]=w;d[y][x]=w;
    } 
    spfa();
    double mn= MX * 1.0;
    for(int i=0;i<=(1<<n)-1;i++)
        if(mn>dp[i][de])
            mn=dp[i][de];
    if(mn>=MX*1.0) printf("Impossible\n");
    else printf("%.3lf\n",mn);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值