HDU 3696 Farm Game <SPFA>

来源:互联网 发布:mac双系统win8蓝屏 编辑:程序博客网 时间:2024/06/02 14:42

题目:click~

SPFA最长路,思路如下:

先对题目中给出的每条边建边,权值为转化率;增加一个终点S,每个节点到S建边,权值为该物品的单价。

假设X物品最终转化为了Y物品,那么转化之后得到的钱就是 W[x]*转化率1*转化率2*转化率3*转化率4*.....*P[Y]

现在我们关注 转化率1*转化率2*转化率3*转化率4*.....*P[Y] 这个式子,实际上就是求这个式子的最大值。

怎么求?事实上就是节点X到节点S的最长路。如果这样去求,那么需要N次SPFA;所以我们需要反向建边,从S出发开始求最长路。最终比较一下转换后的价格和之前的价格哪个大,就用哪个。.

#include <iostream>#include <cstdio>#include <string>#include <algorithm>#include <cmath>#include <vector>#include <cstring>#include <queue>using namespace std;const double INF=2100000000.0;const int maxn = 50010;int head[maxn],nxt[maxn],to[maxn],e;double w[maxn],p[maxn],cost[maxn];int a[maxn];double b[maxn];void add(int u,int v,double t){    to[e] = v; nxt[e] = head[u];cost[e] = t; head[u] = e++;}void init(int n){    e = 2;    memset(head,0,sizeof(head));}bool vis[maxn];double dist[maxn];void SPFA(int s){    memset(vis,0,sizeof(vis));    memset(dist,-INF,sizeof(dist));    queue<int> Q;    while(!Q.empty()) Q.pop();    dist[s] = 1;    Q.push(s);vis[s] = true;    while(!Q.empty())    {        int u = Q.front();Q.pop();        vis[u] = false;        for(int e = head[u];e;e=nxt[e])        {            int v = to[e];            if(dist[u]*cost[e]>dist[v])            {                if(!vis[v]) Q.push(v);                dist[v] =dist[u]*cost[e];                vis[v] = true;            }        }    }}int main(){    int n,m;    while(cin >> n&&n)    {        init(n);        for(int i=1;i<=n;i++)            scanf("%lf %lf",&w[i],&p[i]);    for(int i=1;i<=n;i++)    {        add(n+1,i,w[i]);    }        scanf("%d",&m);        for(int i=0;i<m;i++)        {            int k;            scanf("%d",&k);            scanf("%d",&a[0]);            for(int j=1;j<k;j++)            {                scanf("%lf %d",&b[j],&a[j]);                add(a[j],a[j-1],b[j]);            }        }        int s = n+1;        SPFA(s);        double ans = 0;        for(int i=1;i<=n;i++)        {            ans += p[i]*max(w[i],dist[i]);//printf("%.2f\n",ans);        }        printf("%.2f\n",ans);    }    return 0;}




0 0
原创粉丝点击