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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

*【HDU - 5711】Ingress(tsp旅行商问题,优先队列贪心,状压dp,floyd最短路,图论)

發布時間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 *【HDU - 5711】Ingress(tsp旅行商问题,优先队列贪心,状压dp,floyd最短路,图论) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題干:

Brickgao, who profited from your accurate calculating last year, made a great deal of money by moving bricks. Now he became ``gay shy fool'' again and recently he bought an iphone and was deeply addicted into a cellphone game called Ingress. Now he is faced with a problem so he turns to you for help again. We make some slight modifications based on the original rules, so please draw attention to the details below.?

There are?NN?portals (indexed from 1 to?NN) around Brickgao's home, and he can get some substances called XM by hacking the portals. It's known that for each portal?ii, he can get?AiAi?XM during the first hack, and after each hack, the amount of XM he will get during the next hack will decrease by?BiBi. If the amount of XM he can get is less than or equal to zero, Brickgao can't get XM from that portal anymore. For the?ii-th portal, if?Ai=10,Bi=2Ai=10,Bi=2?and he hacks 3 times, he will get 10, 8, 6 XM during each hack.?

There are?MM?bidirectional roads between some pairs of portals and between Brickgao's home and some portals. Now he is eager to start his Ingress journey from home and finally return home, but due to the extremely hot weather, Brickgao will feel sick when you hack more than?KK?times or the distance he covers is more than?LL. So how much XM he can get at most during this journey??
?

Input

The first line contains a single integer?T(T≤20)T(T≤20), indicating the number of test cases.?

The first line of each case are four integers?N(1≤N≤16),M(0≤M≤N(N+1)2),K(1≤K≤50)N(1≤N≤16),M(0≤M≤N(N+1)2),K(1≤K≤50)?and?L(2≤L≤2000)L(2≤L≤2000).?
The second line of each case contains?NN?non-negative integers where the?ii-th denotes?Ai(Ai≤500)Ai(Ai≤500).?
The third line of each case contains?NN?non-negative integers where the?ii-th denotes?Bi(Bi≤50)Bi(Bi≤50).?
Each of next?MM?line contains 3 non-negative integers?u,v(0≤u,v≤n)u,v(0≤u,v≤n)?and?c(0≤c≤1000)c(0≤c≤1000)?, denotes that there is a road with the length of?cc?between the?uu-th and the?vv-th portal. If?uu?or?vv?equals to 0, it means Brickgao's home.?

Output

For each test case, output the case number first, then the amount of maximum XM Brickgao can get.?

Sample Input

2 1 1 3 2 5 3 0 1 1 3 6 3 5 10 7 5 2 3 1 0 1 3 0 2 1 0 3 1 1 2 2 2 3 3 1 3 4

Sample Output

Case 1: 7 Case 2: 16

題目大意:

n(<=16)個點(其實還有個0點為home),m(<=n^2)條雙向邊和邊權(代表兩點之間距離<=1000),K(<=50)次hack機會,最遠走L(<=2000)路程

每個點的初始點權為a[i](<=500),每個點每hack一次點權下降b[i](<=50)(變為負則當然就不選啦)

對于每個點,可以只經過不hack,也可以到這個點之后一次性hack多次。

一個人從home出發,最多hackK次,問在路程不超過L的情況下,可以獲得的最大價值。

解題報告:

因為可以只經過不hack,所以先floyd跑一邊最短路(套路了),然后不難發現可以認為:走過一個點之后不會再走回來,或者說,選擇了這個點hack了,就不會回來再hack這個點(因為還要多走距離,何必呢)(emmm其實上面說走過一個點之后不會再走回來不太合適,因為畢竟因為最短路,所以可能還是要回來的(因為這一點是最短路需要經過的點嘛))這樣我們只需要記錄狀態:走過了哪些點,當前在哪個點上,就可以跑(2^n * n)的dp了。
dp[sta][i]表示目前經過點的狀態集合為i,當前所在點的位置為 i 的最小路徑(當然要加上返程到0點的路徑)
這是典型的旅行商問題。
由此得出所有可以到達的合法點集,其狀態用2進制表示為sta。

對于每一個狀態sta,只要dp[sta][i]有一個i符合<=L,那么稱sta是合法狀態。
然后依次枚舉所有的合法sta,
對于每一個合法sta的所有點權,用貪心原則,用優先隊列選取最大的權值。

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 22; int dis[MAX][MAX],dp[1<<17][17]; int a[MAX],b[MAX]; int n,m,k,L; int up; bool ok[1<<17]; void floyd() {for(int k = 0; k<=n; k++) {for(int i = 0; i<=n; i++) {for(int j = 0; j<=n; j++) {dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);}}} } int tsp() {int ans = 0;for(int sta = 0; sta < up; sta++) ok[sta] = 0;memset(dp,0x3f,sizeof dp);dp[1][0]=0;for(int sta = 0; sta < up; sta++) {for(int i = 0; i<=n; i++) {if(dp[sta][i] <= L) {if(dp[sta][i] + dis[i][0] <= L) ok[sta] = 1;for(int j = 1; j<=n; j++) {dp[sta|(1<<j)][j] = min(dp[sta|1<<j][j], dp[sta][i] + dis[i][j]);}}}if(ok[sta]) {priority_queue<PII> pq;for(int i = 1; i<=n; i++) {if((sta&(1<<i) )!= 0) pq.push(pm(a[i],b[i]));}int tmp = 0;for(int i = 1; i<=k; i++) {if(pq.empty()) break;PII cur = pq.top();pq.pop();tmp += cur.F;cur.F -= cur.S;if(cur.F > 0) pq.push(pm(cur.F,cur.S)); }ans = max(ans,tmp);}}return ans; }int main() {int t,iCase=0;cin>>t;while(t--) {scanf("%d%d%d%d",&n,&m,&k,&L);up = (1<<(n+1));memset(dis,0x3f,sizeof dis);for(int i = 0; i<=n; i++) dis[i][i]=0;for(int i = 1; i<=n; i++) scanf("%d",a+i);for(int i = 1; i<=n; i++) scanf("%d",b+i);for(int q,w,e,i = 1; i<=m; i++) {scanf("%d%d%d",&q,&w,&e);if(e < dis[q][w]) dis[q][w]=dis[w][q]=e;}floyd();printf("Case %d: %d\n",++iCase,tsp());} return 0 ; }

貼另一個做法:https://blog.csdn.net/qq_37025443/article/details/83513413

總結

以上是生活随笔為你收集整理的*【HDU - 5711】Ingress(tsp旅行商问题,优先队列贪心,状压dp,floyd最短路,图论)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。