Gym 101617J
Title:
For n gold mines, each gold mine has an initial value representing the amount of gold contained in the first day, reducing di every day. Now, starting from gold mine 1, ask how much gold you can get at most.
Ideas:
Thinking in the way of bfs, for each state is to search violently along the path, using the idea of bfs layer, the time for gold mining is also reasonable, but it will time out, so optimization is needed.
1. There is a maximum time for time, which can be calculated by input 2. There are different ways to arrive at a certain gold mine. Record the time of arrival and the amount of gold obtained, and judge whether it is the best or not each time. 3. When searching for gold deposits, they are arranged in chronological order from small to large, and many calculations can be avoided by choosing the earlier time first each time.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1005;
int n,m;
int ans;
int dp[maxn][maxn];
int d[maxn],v[maxn];
int head[maxn],pos;
int Mday;
struct Node
{
int to,v,next;
}edge[maxn*2];
struct Gold
{
int now;
int val;
int day;
bool operator<(const Gold& b)const
{
return day>b.day;
}
};
void add_edge(int u,int v,int w)
{
edge[pos].to = v;
edge[pos].v = w;
edge[pos].next = head[u];
head[u] = pos++;
}
void bfs()
{
priority_queue<Gold>Q;
Gold a;
a.day = 1;
a.now = 1;
a.val = v[1];
Q.push(a);
ans = v[1];
dp[1][1] = v[1];
while(!Q.empty()) {
Gold t1 = Q.top();
Q.pop();
int u = t1.now;
for(int i = head[u];i != -1; i = edge[i].next) {
int to = edge[i].to;
Gold temp = t1;
temp.day = t1.day + edge[i].v;
temp.now = to;
temp.val += max(0,v[to]-d[to]*(t1.day+edge[i].v-1));
if(temp.day > Mday) continue;
if(temp.val <= dp[to][temp.day]) continue;
Q.push(temp);
dp[to][temp.day] = temp.val;
ans = max(ans,temp.val);
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
memset(head,-1,sizeof(head));
memset(dp,0,sizeof(dp));
ans = 0;
scanf("%d%d",&n,&m);
Mday = 0;
for(int i = 1;i <= n; i++) {
scanf("%d%d",&v[i],&d[i]);
Mday = max(Mday,v[i]/d[i]+1);
}
pos = 0;
for(int i = 1;i <= m; i++) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
bfs();
printf("%d\n",ans);
return 0;
}