挑战程序设计竞赛---POJ.2686

来源:互联网 发布:招聘python 编辑:程序博客网 时间:2024/06/06 01:15

【题意】

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

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

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

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


【解题方法】比较裸的状压dp了,dp[S][v]代表当前消耗了S集合的车票走到v花费的最小时间,可以用spfa来转移也可以直接转移,因为这个图是一个DAG!

【AC代码】

//POJ.2686//Traveling by Stagecoach.//DAG 的直接转移#include <vector>#include <cstdio>#include <iostream>#include <algorithm>using namespace std;#define INF 1e9const int maxn=33;int n,m,p,a,b;typedef pair<int,int>P;vector<P>G[maxn];int ticket[10];double dp[1<<10][33];//消耗了s集合的票到达v花费的最小时间void init(){    for(int i=0; i<300; i++)    {        fill(dp[i],dp[i]+32,INF);    }    for(int i=0; i<=m; i++) G[i].clear();}int main(){    int u,v,w;    while(scanf("%d%d%d%d%d",&n,&m,&p,&a,&b)!=EOF)    {        if(n==0&&m==0&&p==0&&a==0&&b==0) break;        for(int i=0; i<n; i++) scanf("%d",&ticket[i]);        init();        for(int i=1; i<=p; i++)        {            scanf("%d%d%d",&u,&v,&w);            G[u].push_back(make_pair(v,w));            G[v].push_back(make_pair(u,w));        }        dp[0][a]=0;        double res=INF;        int to,weight;        for(int S=0; S<(1<<n); S++)        {//            res=min(res,dp[S][b]);            for(int v=1; v<=m; v++)            {                for(int i=0; i<n; i++)                {                    if(!(S&(1<<i))){//                        puts("success");                        //使用了车票i,从v点移动到了to点                        for(int u=0; u<(int)G[v].size(); u++)                        {                            to=G[v][u].first;                            weight=G[v][u].second;                            dp[S|(1<<i)][to] = min(dp[S|(1<<i)][to],dp[S][v]+(double)weight/ticket[i]);                        }                    }                }            }            res=min(res,dp[S][b]);        }        if(res==INF)        {            printf("Impossible\n");        }        else        {            printf("%.3f\n",res);        }    }}//Spfa 转移#include <queue>#include <vector>#include <cstdio>#include <string.h>#include <iostream>#include <algorithm>using namespace std;#define INF 1e9const int maxn=33;int n,m,p,a,b;int vis[300][33];typedef pair<int,int>P;vector<P>G[maxn];double dp[300][33];int ticket[33];void init(){    for(int i=0; i<300; i++) fill(dp[i],dp[i]+32,INF);    for(int i=0; i<=m; i++)   G[i].clear();    memset(vis,false,sizeof(vis));}void spfa(){    queue<P>qu;    memset(vis,false,sizeof(vis));    while(!qu.empty()) qu.pop();    dp[0][a]=0;    vis[0][a]=1;    qu.push(make_pair(0,a));    P now;    while(!qu.empty())    {        now=qu.front();        qu.pop();        int S=now.first;        int v=now.second;        for(int i=0; i<n; i++)        {            if(!(S&(1<<i)))            {                for(int u=0; u<(int)G[v].size(); u++)                {                    int to=G[v][u].first;                    int weight=G[v][u].second;                    if(dp[S|(1<<i)][to]>dp[S][v]+(double)weight/ticket[i])                    {                        dp[S|(1<<i)][to]=dp[S][v]+(double)weight/ticket[i];                        if(!vis[S|(1<<i)][to])                        {                            vis[S|(1<<i)][to]=1;                            qu.push(make_pair(S|(1<<i),to));                        }                    }                }            }        }    }    double res=INF;    for(int i=0; i<(1<<n); i++) res=min(res,dp[i][b]);    if(res!=INF)        printf("%.3f\n",res);    else        printf("Impossible\n");}int main(){    while(scanf("%d%d%d%d%d",&n,&m,&p,&a,&b)!=EOF)    {        if(n==0&&m==0&&p==0&&a==0&&b==0) break;        int u,v,w;        init();        for(int i=0; i<n; i++) scanf("%d",&ticket[i]);        for(int i=0; i<p; 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();    }}





0 0
原创粉丝点击