NYOJ 203 三國誌(Dijkstra+貪心)
三國誌
時間限制:3000 ms | 內存限制:65535 KB 難度:5- 描寫敘述
-
《三國誌》是一款非常經典的經營策略類遊戲。我們的小白同學是這款遊戲的忠實玩家。如今他把遊戲簡化一下,地圖上僅僅有他一方勢力,如今他僅僅有一個城池,而他周邊有一些無人占的空城,可是這些空城中有非常多不同數量的同種財寶。
我們的小白同學虎視眈眈的看著這些城池中的財寶。
依照遊戲的規則。他僅僅要指派一名武將攻占這座城池,裏面的財寶就歸他全部了。只是一量攻占這座城池,我們的武將就要留守。不能撤回。由於我們的小白手下有無數的武將,所以他不在乎這些。
從小白的城池派出的武將,每走一公理的距離就要消耗一石的糧食,而他手上的糧食是有限的。如今小白統計出了地圖上城池間的道路,這些道路都是雙向的。他想請你幫忙計算出他能得到 的最多的財寶數量。我們用城池的編號代表城池,規定小白所在的城池為0號城池。其它的城池從1號開始計數。
- 輸入
- 本題包括多組數據:
首先,是一個整數T(1<=T<=20),代表數據的組數
然後,以下是T組測試數據。對於每組數據包括三行:
第一行:三個數字S,N,M
(1<=S<=1000000,1<=N<=100,1<=M<=10000)
S代表他手中的糧食(石),N代表城池個數。M代表道路條數。
第二行:包括M個三元組行 Ai,Bi,Ci(1<=A,B<=N,1<=C<=100)。
代表Ai,Bi兩城池間的道路長度為Ci(公裏)。
第三行:包括N個元素,Vi代表第i個城池中的財寶數量。(1<=V<=100)
- 輸出
- 每組輸出各占一行。輸出僅一個整數,表示小白能得到的最大財富值。
- 例子輸入
-
2 10 1 1 0 1 3 2 5 2 3 0 1 2 0 2 4 1 2 1 2 3
- 例子輸出
-
2 5
-
Dijkstra+貪心算法!
-
AC碼:
-
#include<stdio.h> #include<string.h> #define INF 99999999 int G[105][105],visit[105],num[105]; int dist[105],dp[1000005]; int max(int a,int b) { return a>b?
a:b; } int main() { int T,s,n,m,a,b,c,min,i,j,k; scanf("%d",&T); while(T--) { scanf("%d%d%d",&s,&n,&m); for(i=0;i<=n;i++) { for(j=0;j<=n;j++) G[i][j]=INF; } for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); if(G[a][b]>c) // WA了非常多次,不知道為什麽要加這個推斷條件 G[a][b]=G[b][a]=c; // 創建鄰接矩陣 } for(i=1;i<=n;i++) scanf("%d",&num[i]); // 每一個城市的財富值 // Dijkstra算法求隨意兩點間的最短路徑 memset(visit,0,sizeof(visit)); for(i=0;i<=n;i++) dist[i]=G[0][i]; dist[0]=0; visit[0]=1; for(i=1;i<=n;i++) { min=INF; k=0; for(j=0;j<=n;j++) { if(!visit[j]&&min>dist[j]) { min=dist[j]; k=j; } } visit[k]=1; for(j=0;j<=n;j++) { if(!visit[j]&&dist[j]>dist[k]+G[k][j]) dist[j]=dist[k]+G[k][j]; } }// 最短路徑求解完成 // 貪心算法求得最大財富值 memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { for(j=s;j>=dist[i];j--) { dp[j]=max(dp[j],dp[j-dist[i]]+num[i]); } } printf("%d\n",dp[s]); } return 0; }
NYOJ 203 三國誌(Dijkstra+貪心)