Gym 101617J Treasure Map(bfs暴力)

http://codeforces.com/gym/101617/attachments

题意:
给出一个图,每个顶点代表一个金矿,每个金矿有g和d两个值,g代表金矿初始的金子量,d是该金矿每天的金子量会减少d。顶点与顶点之间存在边,意思是从一个金矿到另一个金矿需要花费的天数。现在有个人一开始在1金矿,问最多能挖到多少金矿,注意,不能在一个金矿连续挖几天。

 

思路:
bfs求解,但是需要剪枝,用二位数组d[v][day]记录第day天时在v金矿所能获得的最大值。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 const int maxn = 1000+5;
 7 
 8 int tot,n,m,mx,ans;
 9 int head[maxn];
10 int g[maxn],d[maxn];
11 int dis[maxn][maxn];
12 
13 struct Node
14 {
15     int v,w,next;
16 }e[2*maxn];
17 
18 struct node
19 {
20     int id;
21     int val;
22     int day;
23     bool operator< (const node& rhs) const
24     {
25         return day>rhs.day;
26     }
27 };
28 
29 void addEdge(int u,int v,int w)
30 {
31     e[tot].v = v;
32     e[tot].w = w;
33     e[tot].next = head[u];
34     head[u] = tot++;
35 }
36 
37 void bfs()
38 {
39     memset(dis,0,sizeof(dis));
40     priority_queue<node> q;
41     node p;
42     p.id = 1;
43     p.val = g[1];
44     p.day = 1;
45     q.push(p);
46     ans = g[1];
47 
48     dis[1][1] = g[1];
49     while(!q.empty())
50     {
51         p = q.top(); q.pop();
52         int u = p.id;
53 
54         for(int i=head[u];i!=-1;i=e[i].next)
55         {
56             int v = e[i].v;
57             int w = e[i].w;
58             node tmp = p;
59             tmp.id = v;
60             tmp.val += max(0,g[v]-d[v]*(p.day+w-1));
61             tmp.day = p.day + w;
62             if(tmp.day>mx)  continue;
63             if(tmp.val<=dis[v][tmp.day])  continue;
64             dis[v][tmp.day] = tmp.val;
65             q.push(tmp);
66             ans = max(ans,tmp.val);
67         }
68 
69     }
70 }
71 
72 int main()
73 {
74    //freopen("in.txt","r",stdin);
75     while(~scanf("%d%d",&n,&m))
76     {
77         mx = 0;
78         tot = 0;
79         memset(head,-1,sizeof(head));
80         for(int i=1;i<=n;i++)
81         {
82             scanf("%d%d",&g[i],&d[i]);
83             mx = max(mx,g[i]/d[i]+1);
84         }
85         while(m--)
86         {
87             int u,v,w;
88             scanf("%d%d%d",&u,&v,&w);
89             addEdge(u,v,w);
90             addEdge(v,u,w);
91         }
92         bfs();
93         printf("%d\n",ans);
94     }
95     return 0;
96 }

 

转载于:https://www.cnblogs.com/zyb993963526/p/8039593.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值