- #include
- using namespace std;
- using VI = vector<int>;
- using ll = long long;
- using PII = pair
int>; - const int mod = 998244353;
- int n,m;
- int idx = 0;
- struct edge{
- int from,next,to;
- double bea , cost , val;
- }g[200050];
- VI topsort;
- int head[200050];
- int deg[200050];
- double dp[200050];
- void add(int u , int v ,double bea , double cost){
- idx++;
- g[idx].bea = bea;
- g[idx].cost = cost;
- g[idx].from = u;
- g[idx].to = v;
- g[idx].next = head[u];
- head[u] = idx;
- }
-
- bool check(double mid){
- for(int i = 1 ; i <= idx ; i++){
- g[i].val = g[i].bea - g[i].cost * mid;
- }
- memset(dp , -2 , sizeof dp);
- dp[1] = 0;
- for(auto x : topsort){
- for(int i = head[x] ; i ; i = g[i].next){
- int to = g[i].to;
- dp[to] = max(dp[to] , dp[x] + g[i].val);
- }
- }
- return dp[n] >= 0;
- }
-
-
- int main(){
- cin>>n>>m;
- for(int i = 1 ; i <= m ; i++){
- int u,v;
- double bea,cost;
- cin>>u>>v>>bea>>cost;
- add(u , v , bea , cost);
- deg[v]++;
- }
- queue<int> q;
- for(int i = 1 ; i <= n ; i++){
- if(deg[i] == 0) q.push(i);
- }
- while(q.size()){
- auto x = q.front();
- q.pop();
- topsort.push_back(x);
- for(int i = head[x] ; i ; i = g[i].next){
- int to = g[i].to;
- deg[to]--;
- if(deg[to] == 0)q.push(to);
- }
- }
- double left = 0 ;
- double right = 1e18;
- while(right - left > 1e-10){
- double mid = (left + right) / 2;
- if(check(mid)) left = mid;
- else right = mid ;
- }
- //cout<
- printf("%.10lf" , left);
- }
二分一个答案,重新设置边权 bea - mid * cost;
跑拓扑 + dp