題目描述
小胖和zyr要去esqms森林採蘑菇。
esqms森林間有n個小樹叢,m條小徑,每條小徑都是單向的,連線兩個小樹叢,上面都有一定數量的蘑菇。小胖和zyr經過某條小徑一次,可以採走這條路上所有的蘑菇。由於esqms森林是一片神奇的沃土,所以一條路上的蘑菇被採過後,又會長出一些新的蘑菇,數量為原來蘑菇的數量乘上這條路的「恢復係數」,再下取整。
比如,一條路上有4個蘑菇,這條路的「恢復係數」為0.7,則第一~四次經過這條路徑所能採到的蘑菇數量分別為4,2,1,0.
現在,小胖和zyr從s號小樹叢出發,求他們最多能採到多少蘑菇。
對於30%的資料,n<=7,m<=15
另有30%的資料,滿足所有「恢復係數」為0
對於100%的資料,n<=80,000,m<=200,000,0.1<=恢復係數<=0.8且僅有一位小數,1<=s<=n.
輸入輸出格式
輸入格式:
第一行,n和m
第2……m+1行,每行4個數字,分別表示一條小路的起點,終點,初始蘑菇數,恢復係數。
第m+2行,乙個數字s
輸出格式:
乙個數字,表示最多能採到多少蘑菇,在int32範圍內。
輸入輸出樣例
輸入樣例#1:
3 3
1 2 4 0.5
1 3 7 0.1
2 3 4 0.6
1 輸出樣例#1:
8tarjan縮點+spfa
先跑一邊tarjan,縮點,重構圖,變成dag,再搞spfa求最長路。
洛谷的資料有點奇怪,一開始打錯了沒考慮點權給過了,加上點權又過了。
標程的雙端佇列優化不是很懂,而且並不是特別快,494ms。自己的**不加優化560ms,試著加優化以後最快達到了372ms,洛谷給過了,,,,
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn=200000+2;
int first[maxn],nxt[maxn],tot=0;
int dfn[maxn],low[maxn],scc[maxn],size[maxn],val[maxn];
int scc_num,dfs_clock;
int dist[maxn];
int n,m,s;
bool used[maxn];
stack
s;struct edge
l[maxn];
void build(int f,int t,int v,double c)
; nxt[tot]=first[f];
first[f]=tot;
}void clear()
void dfs(int u)
else
if(!scc[w])
}if(low[u]==dfn[u])
}return;
}int get_val(int i)//計算出每一條邊的總權值
return ans;
}void rebuild()//縮點、重構圖
}clear();//將之前的圖全部清空
for(int i=1;i<=m;i++)//遍歷每一條邊
}void spfa(int s)//最長路}}
}}int main()
scanf("%d",&s);
dfs(s);//因為起點固定,所以只需要跑起點所在的環
rebuild();
spfa(scc[s]);
int ans=0;
for(int i=1;i<=n;i++)
cout
<'\n';
return
0;}
洛谷2656 採蘑菇
洛谷2656 採蘑菇 題目描述 小胖和zyr要去esqms森林採蘑菇。esqms森林間有n個小樹叢,m條小徑,每條小徑都是單向的,連線兩個小樹叢,上面都有一定數量的蘑菇。小胖和zyr經過某條小徑一次,可以採走這條路上所有的蘑菇。由於esqms森林是一片神奇的沃土,所以一條路上的蘑菇被採過後,又會長出...
洛谷P2656 採蘑菇
include include include include include include using namespace std struct inter 200040 double hui 200040 bool flag 80080 int n,m,x,y,z,s,ans 80080 f1...
洛谷 P2656 採蘑菇(Tarjan縮點,dp)
對於每一條路,很顯然只有兩種情況,一種是走一次,一種是走無限次,而第二種情況的條件是這條邊在乙個環中。所以先用tarjan縮點,每個點的權值更新為這個環上所有邊一直摘的蘑菇數的和。然後跑一邊既有邊權也有點權的dag上的dp即可。資料有鍋,後四個點答案有誤,用double存實際上錯了,但是標程是dou...