E - Coins Respawn
Time Limit: 2 sec / Memory Limit: 1024 MB
配点 : 500500 点
11 から NN までの番号がつけられた NN 頂点と MM 辺からなる有向グラフがあります。 ii 番目の辺は頂点 AiAi から頂点 BiBi へと向かい、この辺の上には CiCi 枚のコインが置かれています。 また、頂点 NN にはボタンが設置されています。
このグラフ上でゲームを行います。 あなたは頂点 11 でコインを 00 枚持ってゲームを開始し、辺をたどってコインを拾いながら頂点 NN を目指します。 11 本の辺を通るには 11 分の時間がかかり、辺を通るたびにその辺の上に置かれているすべてのコインを拾うことができます。 ゲームの世界ではよくあるように、ある辺を通ってその上のコインを拾っても、その辺を次に通る際には同じ枚数のコインが再び出現しており、それらを再び拾うことができます。
頂点 NN に到着したとき、ボタンを押してゲームを終了することができます。(ボタンを押さずに移動を続けることもできます。) ただし、ゲームを終了する際に、ゲーム開始からの経過時間を TT 分として T×PT×P 枚のコインの支払いが要求されます。持っているコインの枚数が T×PT×P 枚未満の場合は、代わりに持っているコインをすべて支払います。
この支払いの後に残ったコインの枚数があなたのスコアとなります。 獲得できるスコアの最大値が存在するか判定し、存在する場合はその最大値を求めてください。
入力は以下の形式で標準入力から与えられる。
NN
MM
PP
A1A1
B1B1
C1C1
::
AMAM
BMBM
CMCM
獲得できるスコアの最大値が存在する場合はその最大値を、存在しない場合は -1
を出力せよ。
Copy
3 3 10
1 2 20
2 3 30
1 3 45
Copy
35
頂点 11 から頂点 33 に移動する方法は以下の 22 通りです。
よって、獲得できるスコアの最大値は 3535 です。
Copy
2 2 10
1 2 100
2 2 100
Copy
-1
頂点 11 から伸びる辺を通ると頂点 22 に着き、ここで頂点 22 から自分自身へと向かう辺を tt 回通ってからボタンを押すとスコアは 90+90t90+90t となります。よってスコアは無限に高めることができ、獲得できるスコアの最大値は存在しません。
Copy
4 5 10
1 2 1
1 4 1
3 4 1
2 2 100
3 3 100
Copy
0
頂点 11 から頂点 44 へと直接向かう辺を通ること以外に頂点 11 から頂点 44 に移動する方法はありません。この辺の上で 11 枚のコインを拾いますが、ゲーム終了時に 1010 枚のコインの支払いを要求されてスコアは 00 となります。
なお、頂点 11 から頂点 22 へと向かう辺を通るとその後コインを無限に拾えますが、頂点 44 に到達してゲームを終了することができなくなるため無意味です。
Score : 500500 points
There is a directed graph with NN vertices numbered 11 to NN and MM edges. The ii -th edge is directed from Vertex AiAi to Vertex BiBi , and there are CiCi coins placed along that edge. Additionally, there is a button on Vertex NN .
We will play a game on this graph. You start the game on Vertex 11 with zero coins, and head for Vertex NN by traversing the edges while collecting coins. It takes one minute to traverse an edge, and you can collect the coins placed along the edge each time you traverse it. As usual in games, even if you traverse an edge once and collect the coins, the same number of coins will reappear next time you traverse that edge, which you can collect again.
When you reach Vertex NN , you can end the game by pressing the button. (You can also choose to leave Vertex NN without pressing the button and continue traveling.) However, when you end the game, you will be asked to pay T×PT×P coins, where TT is the number of minutes elapsed since the start of the game. If you have less than T×PT×P coins, you will have to pay all of your coins instead.
Your score will be the number of coins you have after this payment. Determine if there exists a maximum value of the score that can be obtained. If the answer is yes, find that maximum value.
Input is given from Standard Input in the following format:
NN
MM
PP
A1A1
B1B1
C1C1
::
AMAM
BMBM
CMCM
If there exists a maximum value of the score that can be obtained, print that maximum value; otherwise, print -1
.
Copy
3 3 10
1 2 20
2 3 30
1 3 45
Copy
35
There are two ways to travel from Vertex 11 to Vertex 33 :
Thus, the maximum score that can be obtained is 3535 .
Copy
2 2 10
1 2 100
2 2 100
Copy
-1
The edge extending from Vertex 11 takes you to Vertex 22 . If you then traverse the edge extending from Vertex 22 to itself tt times and press the button, your score will be 90+90t90+90t . Thus, you can infinitely increase your score, which means there is no maximum value of the score that can be obtained.
Copy
4 5 10
1 2 1
1 4 1
3 4 1
2 2 100
3 3 100
Copy
0
There is no way to travel from Vertex 11 to Vertex 44 other than traversing the edge leading from Vertex 11 to Vertex 44 directly. You will pick up one coin along this edge, but after being asked to paying 1010 coins, your score will be 00 .
Note that you can collect an infinite number of coins if you traverse the edge leading from Vertex 11 to Vertex 22 , but this is pointless since you can no longer reach Vertex 44 and end the game.
https://atcoder.jp/contests/abc137/tasks/abc137_e
所有边权减去p
跑最长路 比赛时数据可以Pass
被一些莫名其妙的数据hack
需要注意哪些点对结果有影响
1能够到达的点以及能够到达n的点
把他们标记下来
跑最长路即可
如果跑完还可以松弛
那么说明有环
AC代码
#include
using namespace std;
const int maxn=2e5+10;
typedef long long ll;
struct Edge
{
ll v,cost,nxt;
};
Edge edge[maxn];
ll head[maxn];
ll dis[maxn];
int flag[maxn];
int ok[maxn];
ll cnt;
ll tp[maxn];
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
memset(flag,0,sizeof(flag));
memset(edge,0,sizeof(edge));
for(ll i=2;i0)
{
printf("%lld\n",dis[n]);
}
else
{
printf("0\n");
}
return 0;
}