當前位置:
首頁 >
POJ - 3635 Full Tank?(bfs)
發布時間:2024/4/11
50
豆豆
生活随笔
收集整理的這篇文章主要介紹了
POJ - 3635 Full Tank?(bfs)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一個無環無向圖,每個點都可以看做一個補給站,油價是固定的,每條路都要消耗一定的油量,給出q個詢問,問油箱大小為c,從起點到終點所需要的最小花費
題目分析:可以用bfs+優先隊列直接爆搜,我們令每個狀態都是一個二元組(x,y)代表的是在x點剩y升油,則每個點(u,f)都可以更新為(u,f+1)和(v,f-w)兩個狀態,因為c給的很小,只有100,總的時間復雜度最差也是n*c*q=1000*100*100=1e7,在算上點常數時間開銷,1秒跑完這個題也是穩穩的了。
優先隊列中我維護了三個變量,分別是當前節點,當前剩余油量,當前花銷,對于花銷重載小于號,這樣就能保證到達終點時的第一個點一定是最優解。網上我看有的題解還用動態規劃的思想維護了一個二維cost數組,用來記錄到x點時剩余油量為y的最小花費,我個人感覺沒必要,因為用了優先隊列后求出的答案一定是最優解了,如果再同時維護一個cost數組就是給自己找麻煩,但換個想法,如果用cost數組搭配普通隊列或許會更快,前兩天也是做了一個題,就是需要維護一個數組來進行條件判斷
因為代碼寫的有點亂,湊活看吧,因為多次出現了結構體的調用,之后如果有空會再寫寫隊列+動態規劃的形式,說不定會快一點
直接上代碼了,優先隊列+bfs:
#include<iostream> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e3+100;struct Node {int to,w,f;Node(int TO,int W){to=TO;w=W;f=0;}Node(int TO,int W,int F){to=TO;w=W;f=F;}bool operator<(const Node& a)const{return w>a.w;} };vector<Node>node[N];int n,m;int c,s,e;int ans;int p[N]; bool vis[N][N];bool bfs() {memset(vis,false,sizeof(vis));priority_queue<Node>q;q.push(Node(s,0,0));vis[s][0]=true;while(!q.empty()){Node cur=q.top();q.pop();if(cur.to==e){ans=cur.w;return true;}if(cur.f<c&&!vis[cur.to][cur.f+1]){ // vis[cur.to][cur.f+1]=true; //不要加這句話,會WA,因為vis記錄的是轉移過后的狀態,這里雖然也是轉移狀態 //但最多算是起點而不是終點,換句話說,這里更新的狀態是讓cost變大,我們的目的是盡可能讓cost變小 //如果我們在這里將cur.to,cur.f+1這個狀態標記掉了,那么可能讓下面的最優解無法遍歷到 //可以將這里的更新理解為初始化,然后后續肯定會有最優解來更新掉這個答案 //我反正感覺這一句話是這個程序中最難想的一個點了。。可能是我太菜了q.push(Node(cur.to,cur.w+p[cur.to],cur.f+1));}for(int i=0;i<node[cur.to].size();i++){int u=cur.to;int v=node[cur.to][i].to;int w=node[cur.to][i].w;if(cur.f<w)continue;if(vis[v][cur.f-w])continue;vis[v][cur.f-w]=true;q.push(Node(v,cur.w,cur.f-w));}}return false; }int main() {while(scanf("%d%d",&n,&m)!=EOF){for(int i=0;i<n;i++){scanf("%d",p+i);node[i].clear();}while(m--){int u,v,w;scanf("%d%d%d",&u,&v,&w);node[u].push_back(Node(v,w));node[v].push_back(Node(u,w));}int q;scanf("%d",&q);while(q--){scanf("%d%d%d",&c,&s,&e);if(bfs())printf("%d\n",ans);elseprintf("impossible\n");}}return 0; }?
總結
以上是生活随笔為你收集整理的POJ - 3635 Full Tank?(bfs)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 1475 Pushing B
- 下一篇: 区间1~n的异或值