1. 程式人生 > >poj-1724(bfs+優先隊列)

poj-1724(bfs+優先隊列)

CI size ext pop esp break TE eof OS

題意:有向圖,給你m條邊,每條邊有兩個權值,路徑長和通過這條路徑的花費,問你在不超過k花費的前提下,最短的路徑從1走到n

解題思路:因為邊數很少,我們可以直接用暴力每條邊的方式來找最小的路徑長,也就是用一個優先隊列,每次彈出路徑最短的邊,計算當前花費和下條邊的花費如果小於k,那麽這條邊就可行。

很多博客寫是迪傑斯特拉+heap,我覺得沒有松弛過程的應該算不上單元最短路的寫法把(QAQ);

代碼:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#define maxn 100000
#define inf 1e9
using namespace std;
struct Edge
{
    int next;
    int to;
    int w;
    int c;
}edge[maxn];
struct node
{
    int num;
    int dist;
    int cost;
    node(int _num=0,int _dist=0,int _cost=0):num(_num),dist(_dist),cost(_cost){}
    bool operator < (const node &a) const
	{
		return a.dist<dist;
	}

};
int head[maxn];
int cnt;
int dist[maxn];
int k,n,m;
void add(int u,int v,int w,int c)
{
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].c=c;
    edge[cnt].next=head[u];
    head[u]=cnt++;

}
int dij(int x)
{
    int ans=-1;
    node u,v;
    priority_queue<node>que;
    que.push(node(x,0,0));
    while(!que.empty())
    {
        node u=que.top();
        que.pop();
        int now=u.num;
        if(now==n)
        {
            ans=u.dist;
            return ans;
            break;
        }
        for(int i=head[now];i!=-1;i=edge[i].next)
        {
            if(u.cost+edge[i].c<=k)
            {
                v.num=edge[i].to;
                v.dist=u.dist+edge[i].w;
                v.cost=u.cost+edge[i].c;
                que.push(v);
            }
        }
    }
    return ans;
}
int main()
{
    int x,y,w,c;

    while(cin>>k>>n>>m)
    {
        memset(head,-1,sizeof(head));
            cnt=0;
        for(int i=1;i<=m;i++)
        {
            cin>>x>>y>>w>>c;
            add(x,y,w,c);
        }
        cout<<dij(1)<<endl;
    }

}

  

poj-1724(bfs+優先隊列)