UVA-11367 Full Tank? (dijkstra)

题目大意:有n个加油站,每个加油站的油价已知,并且已知油箱的大小,问能否从起点走到终点,若能,找出最小油费。

题目分析:记得在做暴力搜索的时候做过这道题,不算难。但是这次是用dijkstra算法做的,时间复杂度不理想,差一点超时(1.9s,限制是2s)。用BFS做的话要快很多。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))

const int INF=1<<30;
struct Node
{
    int u,k;
    Node(int _u,int _k):u(_u),k(_k){}
};
const int N=1005;
struct Edge
{
    int to,nxt,w;
};
Edge e[N*20];
int inq[N][105],dis[N][105],head[N],p[N],n,m,cnt;

void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].nxt=head[u];
    head[u]=cnt++;
}

int dijkstra(int C,int s,int t)
{
    CL(inq,0);
    REP(i,0,n) REP(j,0,C+1) dis[i][j]=INF;
    queue<Node>q;
    q.push(Node(s,0));
    dis[s][0]=0;
    while(!q.empty())
    {
        Node top=q.front();
        q.pop();
        int u=top.u,k=top.k;
        inq[u][k]=0;
        for(int i=head[u];i!=-1;i=e[i].nxt){
            int v=e[i].to;
            if(k>=e[i].w&&dis[v][k-e[i].w]>dis[u][k]){
                dis[v][k-e[i].w]=dis[u][k];
                if(!inq[v][k-e[i].w]){
                    inq[v][k-e[i].w]=1;
                    q.push(Node(v,k-e[i].w));
                }
            }
            if(k<C&&dis[u][k+1]>dis[u][k]+p[u]){
                dis[u][k+1]=dis[u][k]+p[u];
                if(!inq[u][k+1]){
                    inq[u][k+1]=1;
                    q.push(Node(u,k+1));
                }
            }
        }
    }
    int res=INF;
    REP(i,0,C+1) res=min(res,dis[t][i]);
    return res;
}

int main()
{
    int a,b,c,query;
    while(~scanf("%d%d",&n,&m)){
        cnt=0;
        CL(head,-1);
        REP(i,0,n) scanf("%d",p+i);
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        scanf("%d",&query);
        while(query--)
        {
            scanf("%d%d%d",&a,&b,&c);
            int k=dijkstra(a,b,c);
            if(k==INF)
                printf("impossible\n");
            else
                printf("%d\n",k);
        }
    }
    return 0;
}

  

posted @ 2015-10-31 21:49  20143605  阅读(250)  评论(0编辑  收藏  举报