【迷宮遊戲】【51Nod - 1459】(dijkstra)
阿新 • • 發佈:2018-11-19
題目:
你來到一個迷宮前。該迷宮由若干個房間組成,每個房間都有一個得分,第一次進入這個房間,你就可以得到這個分數。還有若干雙向道路連結這些房間,你沿著這些道路從一個房間走到另外一個房間需要一些時間。遊戲規定了你的起點和終點房間,你首要目標是從起點儘快到達終點,在滿足首要目標的前提下,使得你的得分總和儘可能大。現在問題來了,給定房間、道路、分數、起點和終點等全部資訊,你能計算在儘快離開迷宮的前提下,你的最大得分是多少麼?
Input
第一行4個整數n (<=500), m, start, end。n表示房間的個數,房間編號從0到(n - 1),m表示道路數,任意兩個房間之間最多隻有一條道路,start和end表示起點和終點房間的編號。
第二行包含n個空格分隔的正整數(不超過600),表示進入每個房間你的得分。
再接下來m行,每行3個空格分隔的整數x, y, z (0 輸入保證從start到end至少有一條路徑。
Output
一行,兩個空格分隔的整數,第一個表示你最少需要的時間,第二個表示你在最少時間前提下可以獲得的最大得分。
Sample Input
3 2 0 2 1 2 3 0 1 10 1 2 11
Sample Output
21 6
解題報告:尋找最短路的一道題目,只不過是有一些優化,就是在最短路的前提下儘可能的最多分。這就是在基礎的最短路上增加了一個優化。
ac程式碼:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define maxn 555 #define inf 99999999 using namespace std; int n,m; int e[maxn][maxn]; int dis[maxn]; int mark[maxn]; int garde[maxn]; int ans[maxn]; void init() { for(int i=0;i<n;i++) for(int j=0;j<=n;j++) { if(i==j) e[i][j]=0; else e[i][j]=e[j][i]=inf; } } void dijkstra(int start,int end) { for(int i=0;i<n;i++) { dis[i]=e[start][i]; } dis[start]=0; ans[start]=garde[start]; // mark[start]=1; for(int i=0;i<n;i++) { int minx=inf; int u=start; for(int j=0;j<n;j++) { if(mark[j]==0&&dis[j]<minx) { minx=dis[j]; u=j; } } // if(u==end) // break; mark[u]=1; for(int v=0;v<n;v++) { if(mark[v]==0&&dis[v]>dis[u]+e[u][v]) { dis[v]=dis[u]+e[u][v]; ans[v]=ans[u]+garde[v]; } else if(mark[v]==0&&dis[v]==dis[u]+e[u][v]) ans[v]=max(ans[u]+garde[v],ans[v]); } } } int main() { int start,end; scanf("%d%d%d%d",&n,&m,&start,&end); init(); for(int i=0;i<n;i++) scanf("%d",&garde[i]); memset(mark,0,sizeof(mark)); memset(ans,0,sizeof(ans)); for(int i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(e[a][b]>c) e[a][b]=e[b][a]=c; } dijkstra(start,end); printf("%d %d\n",dis[end],ans[end]); }