Description
During the trip, Yehan and Linlin pass a cave, and there is a board at the door, which says if you have enough ambition, you will get lots of money from me. At the beginning of the cave, you will get one dollar, and then, if you go from A to B (A and B are two vertexs of an edge, and C is the length of the edge), your money will be C times larger, for example, if you have x dollars, your dollars will be C*x dollars. And the next second, a directed map appears on the entrance of the cave. After that, Yehan thinks it is a good chance to make a big money, therefore, Yehan wants to calculate how much money she can get at most. Could you help Yehan calculate how much money she can get at most? Because of the result is so large, you should mod 1000000007.You should walk from 1 to n.
Input
The first line of input is 2 integers n, m (the number of vertex, the number of edges)The following m lines,(1<=n<=1e4,1<=m<=1e5)the i-th line contains 3 integers u, v, w (1<=w<=1e9)(two vertexs and the length of the edge), we guarantee that there is no cycle.
Output
The maximum of dollars Yehan can get after mod 1000000007
Sample Input 1
3 3 1 2 100000 2 3 10001 1 3 100000 3 3 1 2 1 2 3 1 1 3 2
Sample Output 1
99993 2
我觉得这个OJ可能又要没了
题意:从1走到n,其中有m条单向路径,走过某条路,当前拥有的价值乘上路径权值,初始价值1,问你走到n时你最多有多少价值。
思路:最长路可以spfa取负值来做,问题在于怎么把乘法转化为加法,这里用取对数log来解决,这样就能用加法算出乘的最多的是多少了。然后我们再用一个东西保存没log前的数据来计算答案。一开始用了回溯来计算最终乘积,debug不出来了...改了直接在算最长路时就计算乘积的结果。70+%的AC率被我拖到了50%emmm
代码:
#include<cstdio> #include<set> #include<vector> #include<cmath> #include<queue> #include<cstring> #include<algorithm> typedef long long ll; using namespace std; const int maxn = 10000+5; const double INF = 0x3f3f3f3f; const ll MOD = 1000000007; struct Edge{ int v; int w; double logw; Edge(int _v = 0, int _w = 0, double _logw = 0): v(_v), w(_w), logw(_logw){} }; vector<Edge> G[maxn]; bool vis[maxn]; double dis[maxn]; ll dist[maxn]; void spfa(int start,int n){ memset(vis,false,sizeof(vis)); for(int i = 1;i <= n;i++) dis[i] = INF; vis[start] = true; dis[start] = 0; dist[start] = 1; queue<int> q; while(!q.empty()) q.pop(); q.push(start); while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = false; for(int i = 0;i < G[u].size();i++){ int v = G[u][i].v; double w = G[u][i].logw; if(dis[v] > dis[u] + w){ //u -> v dis[v] = dis[u] + w; dist[v] = (dist[u] * G[u][i].w) % MOD; if(!vis[v]){ q.push(v); vis[v] = true; } } } } } void addEdge(int u,int v,int w){ double logw = -log(w); G[u].push_back(Edge(v, w, logw)); } int main(){ int n, m; while(scanf("%d%d", &n, &m) != EOF){ for(int i = 1;i <= n;i++) G[i].clear(); int s,e; int t; while(m--){ scanf("%d%d%d", &s, &e, &t); addEdge(s,e,t); } spfa(1, n); printf("%lld ", dist[n]); } return 0; } /* 3 3 1 2 100000 2 3 10001 1 3 100000 3 3 1 2 1 2 3 1 1 3 2 */