日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

中石油训练赛 - Bouldering(最短路+剪枝)

發(fā)布時(shí)間:2024/4/11 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 中石油训练赛 - Bouldering(最短路+剪枝) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目大意:給出一個(gè) n * m 的矩陣,矩陣中有些許數(shù)字,兩個(gè)數(shù)字之間的距離如果小于 r 的話(huà)就是可達(dá),到達(dá)一個(gè)數(shù)字后會(huì)消耗數(shù)字對(duì)應(yīng)的體力值,問(wèn)從最下面的數(shù)字到最上面的數(shù)字的最短路是多少,必須要保證體力值不能為負(fù)

題目分析:很容易寫(xiě)出一個(gè)分層圖最短路,嚴(yán)格來(lái)說(shuō)就是個(gè)二維最短路,d[ x ][ s ] 代表從起點(diǎn)到達(dá)點(diǎn) x 時(shí),消耗了 s 點(diǎn)體力的最短路,不過(guò)會(huì) TLE,考慮剪枝

因?yàn)樵谶@個(gè)題目中最短路的優(yōu)先級(jí)最高,換句話(huà)說(shuō),在相同的一個(gè)點(diǎn),肯定距離越近且體力消耗越少越好,如果當(dāng)前 y 位置下,最短距離為 dis,且體力為 s,如果從 y 位置轉(zhuǎn)移過(guò)來(lái)得到的距離 dis' 和 s' ,有關(guān)系 dis' > dis && s' > s,顯然這個(gè)狀態(tài)一定不會(huì)為最后的最后狀態(tài)做出貢獻(xiàn),直接減掉即可

代碼寫(xiě)的有點(diǎn)丑,但還是貼上來(lái)吧

代碼:

//#pragma GCC optimize(2) //#pragma GCC optimize("Ofast","inline","-ffast-math") //#pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e5+100;const double eps=1e-8;int sgn(double x) {if(fabs(x)<=eps)return 0;if(x<0)return -1;elsereturn 1; }struct Node {int x,y,val;Node(int x,int y,int val):x(x),y(y),val(val){}bool operator<(const Node& t)const{return x<t.x;} };struct Edge {int to,next;double w; }edge[30*30*30*30];char maze[30][30];vector<Node>node;int head[30*30],cnt,sum;double d[30*30][25*25*10+100];pair<double,int>mmin[30*30];bool vis[30*30][25*25*10+100];void addedge(int u,int v,double w) {edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++; }struct Node2 {double dis;int to,s;Node2(int to,double dis,int s):to(to),dis(dis),s(s){}bool operator<(const Node2& t)const{if(sgn(dis-t.dis)!=0)return sgn(dis-t.dis)>0;elsereturn s>t.s;} };void Dijkstra(int st) {for(int i=0;i<=node.size();i++){mmin[i]=make_pair(1e10,-1);for(int j=0;j<=sum;j++){d[i][j]=1e10;vis[i][j]=false;}}priority_queue<Node2>q;int s=node[st].val;q.push(Node2(st,0,s));d[st][s]=0;while(q.size()){Node2 cur=q.top();q.pop();int u=cur.to,s=cur.s;if(vis[u][s])continue;vis[u][s]=true;if(sgn(mmin[u].first-d[u][s])>0)//剪枝 mmin[u]=make_pair(d[u][s],s);for(int i=head[u];i!=-1;i=edge[i].next){int to=edge[i].to;double w=edge[i].w;int ss=node[to].val;if(s+ss>sum)continue;if(sgn(d[u][s]+w-mmin[to].first)>=0&&s+ss>=mmin[to].second)continue;if(d[to][s+ss]>d[u][s]+w){d[to][s+ss]=d[u][s]+w;q.push(Node2(to,w+cur.dis,s+ss));}}} }void init() {memset(head,-1,sizeof(head));cnt=0; }int main() { #ifndef ONLINE_JUDGEfreopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);init();int n,m,r,s;scanf("%d%d%d%d",&n,&m,&r,&s);for(int i=1;i<=n;i++)scanf("%s",maze[i]+1);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(maze[i][j]=='.')continue;node.push_back(Node(i,j,maze[i][j]-'0'));sum+=maze[i][j]-'0';}sum=min(sum,s);int st=0,ed=node.size()-1;for(int i=0;i<node.size();i++)for(int j=i+1;j<node.size();j++){double dis=hypot(node[i].x-node[j].x,node[i].y-node[j].y);if(sgn(dis-r)>0)continue;addedge(i,j,dis);addedge(j,i,dis);}Dijkstra(st);double ans=1e10;for(int i=0;i<=sum;i++)ans=min(ans,d[ed][i]);if(sgn(ans-1e10)==0)puts("impossible");elseprintf("%.15f\n",ans);return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的中石油训练赛 - Bouldering(最短路+剪枝)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。