https://ac.nowcoder.com/acm/contest/551/G
题解
题目保证了不会有环。
一开始唯一能确定的一个点便是入度为0的点,确定了一个点自然而然可以推出其他点。
a
1
+
r
1
∗
k
+
(
(
a
1
+
r
1
∗
k
)
+
r
2
∗
k
)
)
+
(
(
(
a
1
+
r
1
∗
k
)
+
r
2
∗
k
)
)
+
r
3
∗
k
)
+
.
.
.
=
s
u
m
a_1+r_1*k+( (a_1+r_1*k)+r_2*k))+(( (a_1+r_1*k)+r_2*k))+r_3*k)+... = sum
a1+r1∗k+((a1+r1∗k)+r2∗k))+(((a1+r1∗k)+r2∗k))+r3∗k)+...=sum
将k
提出来后可以变成k*totval <= tot
,k=tot/val
。
t
o
t
v
a
l
=
∑
1
n
v
a
l
i
+
r
i
totval=\sum_{1}^{n} val_i+r_i
totval=∑1nvali+ri。
拓扑排序一遍求出val
即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define FOR0(a,b) for(int i = a; i < b; ++i)
#define FORE(a,b) for(int i = a; i <= b; ++i)
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2e5+5;
int ind[maxn],n,m;
ll s,k, val[maxn];
vector<pii> G[maxn];
void add(int u, int v,int w) {
G[u].push_back(make_pair(w,v));
}
int vis[maxn];
void solve() {
queue<int> que;
for(int i = 1; i <= n; ++i)
if(ind[i] == 0) que.push(i);
int cnt = 0;
while(!que.empty()) {
int u = que.front();
que.pop();
cnt++;
for(int i = 0; i < G[u].size(); ++i) {
int r = G[u][i].first;
int v = G[u][i].second;
val[v] = max(val[v],val[u]+r);
ind[v]--;
if(ind[v] == 0) que.push(v);
}
}
ll sum = 0;
for(int i = 1; i <= n; ++i) sum += val[i];
//cout << sum << endl;
if(sum > s) {
puts("0");
return;
}
if(sum == 0) cout << -1 << endl;
else cout << (s/sum) << endl;
}
int main() {
scanf("%d%d%lld", &n, &m, &s);
int u, v, w;
for(int i = 0; i < m; ++i) {
scanf("%d%d%d", &u, &v, &w);
add(u,v,w); ind[v]++;
}
solve();
return 0;
}