码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷—— P2656 采蘑菇

时间:2017-10-25 23:58:02      阅读:423      评论:0      收藏:0      [点我收藏+]

标签:line   const   不能   argc   str   tin   nbsp   ack   ret   

https://www.luogu.org/problem/show?pid=2656

题目描述

小胖和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: 复制
8



容易发现当他可以来回走多次采蘑菇的时候,就是出现环的时候,那么就可以将这个环的所有能得到的蘑菇数处理出来。
一遍最短路求出ans、需要注意的是这里两个强连通分量连边时,因为边是有权值的,所以不能只连一条。
 1 #include <cstdio>
 2 #include <vector>
 3 #include <queue>
 4 
 5 #define min(a,b) (a<b?a:b)
 6 
 7 inline void read(int &x)
 8 {
 9     x=0; register char ch=getchar();
10     for(; ch>9||ch<0; ) ch=getchar();
11     for(; ch>=0&&ch<=9; ch=getchar()) x=x*10+ch-0;
12 }
13 const int M(200005);
14 const int N(80005);
15 int n,m,s; double r;
16 int head[N],sumedge;
17 struct Edge {
18     int v,next,w;
19     double r;
20     Edge(int v=0,int next=0,int w=0,double r=0.):v(v),next(next),w(w),r(r){}
21 }edge[M];
22 inline void ins(int u,int v,int w,double r)
23 {
24     edge[++sumedge]=Edge(v,head[u],w,r),head[u]=sumedge;
25 }
26 
27 int tim,low[N],dfn[N];
28 int top,Stack[N],instack[N];
29 int sumcol,col[N],point[N];
30 void DFS(int u)
31 {
32     low[u]=dfn[u]=++tim;
33     Stack[++top]=u,instack[u]=1;
34     for(int v,i=head[u]; i; i=edge[i].next)
35     {
36         v=edge[i].v;
37         if(!dfn[v]) DFS(v), low[u]=min(low[u],low[v]);
38         else if(instack[v]) low[u]=min(low[u],dfn[v]);
39     }
40     if(dfn[u]==low[u])
41     {
42         col[u]=++sumcol;
43         point[sumcol]++;
44         for(; u!=Stack[top]; --top)
45         {
46             col[Stack[top]]=sumcol;
47             point[sumcol]++;
48             instack[u]=0;
49         }
50         instack[u]=0; top--;
51     }
52 }
53 
54 int dis[N];
55 bool inq[N];
56 std::queue<int>que;
57 std::vector< std::pair<int,int> >vec[N];
58 inline int SPFA(int s)
59 {
60     int ret=-1; que.push(s);
61     for(int u,v,w; !que.empty(); )
62     {
63         u=que.front(); que.pop(); inq[u]=0;
64         for(int i=0; i<vec[u].size(); ++i)
65         {
66             v=vec[u][i].first,w=vec[u][i].second;
67             if(dis[v]>=dis[u]+w) continue;
68             dis[v]=dis[u]+w;
69             if(!inq[v]) inq[v]=1,que.push(v);
70         }
71     }
72     for(int i=1; i<=n; ++i) ret=ret>dis[i]?ret:dis[i];
73     return ret;
74 }
75 
76 int Presist()
77 {
78     read(n),read(m);
79     for(int u,v,w,i=1; i<=m; ++i)
80     {
81         read(u),read(v),read(w),
82         scanf("%lf",&r),ins(u,v,w,r);
83     }
84     for(int i=1; i<=n; ++i)
85         if(!dfn[i])    DFS(i);
86     for(int v,u=1; u<=n; ++u)
87         for(int i=head[u]; i; i=edge[i].next)
88         {
89             v=edge[i].v;
90             if(col[v]==col[u])
91                  for(int w=edge[i].w; w; w*=edge[i].r) dis[col[u]]+=w;
92             else vec[col[u]].push_back(std::make_pair(col[v],edge[i].w));
93         }
94     read(s); printf("%d\n",SPFA(col[s]));
95     return 0;
96 }
97 
98 int Aptal=Presist();
99 int main(int argc,char**argv){;}

 

洛谷—— P2656 采蘑菇

标签:line   const   不能   argc   str   tin   nbsp   ack   ret   

原文地址:http://www.cnblogs.com/Shy-key/p/7732653.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!