Hdu 3696 Farm Game(最长路)

来源:互联网 发布:软件著作权变更登记 编辑:程序博客网 时间:2024/04/28 12:20
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3696

思路:每种商品可以直接卖掉,也可以换购后卖掉。所以设点n+1,从该点向每个商品连边权值为log(p[i])(将乘法转换为加法,直接使用SPFA)表示直接卖掉的单位价值;对于可以换购的商品 i-->j,连 j--> i 权值为log(b[j])的边(反向建图,只需求一次最长路),表示单位 i 商品可以转换为b[j] 的 j 商品(求最长路时逐步累乘转换率)。求n+1点到各点的最长路,dist[i]即为单位i商品的最大价值,与 i 商品的数量相乘累加即可。

#include<cstdio>#include<vector>#include<queue>#include<cmath>#include<cstring>#include<iostream>#include<algorithm>#define debuusing namespace std;const int INF=0x3f3f3f3f;const int maxn=1e4+50;struct Node{    int v;    double w;    Node(int v=0,double w=0):v(v),w(w) {}};queue<int> q;vector<Node> g[maxn];double dist[maxn],b[maxn];int v[maxn],n,m,k,a[maxn];double val[maxn],have[maxn];void solve(int s){    memset(v,0,sizeof(v));    while(!q.empty()) q.pop();    for(int i=0; i<=n+1; i++) dist[i]=-INF;    q.push(s),v[s]=0,dist[s]=0;    while(!q.empty())    {        int now=q.front();        q.pop(),v[now]=0;        for(int i=0; i<g[now].size(); i++)        {            int nt=g[now][i].v;            if(dist[nt]<dist[now]+g[now][i].w)            {                dist[nt]=dist[now]+g[now][i].w;                if(!v[nt])                {                    v[nt]=1;                    q.push(nt);                }            }        }    }}int main(){#ifdef debug    freopen("in.in","r",stdin);#endif // debug    while(scanf("%d",&n)==1&&n)    {        for(int i=1; i<=n+1; i++) g[i].clear();        for(int i=1; i<=n; i++)        {            scanf("%lf%lf",&val[i],&have[i]);            g[n+1].push_back(Node(i,log10(val[i])));        }        scanf("%d",&m);        for(int i=1; i<=m; i++)        {            scanf("%d",&k);            scanf("%d",&a[0]);            for(int j=1; j<=k-1; j++)                scanf("%lf%d",&b[j],&a[j]);            for(int j=1; j<=k-1; j++)            {                //cout<<a[j]<<" "<<a[j-1]<<" "<<b[j]*val[a[j]]<<endl;                g[a[j]].push_back(Node(a[j-1],log10(b[j])));            }        }        /*for(int i=1;i<=n+1;i++)        {            for(int j=0;j<g[i].size();j++)                cout<<i<<" "<<g[i][j].v<<" "<<g[i][j].w<<endl;        }*/        solve(n+1);        double ans=0.0;        for(int i=1; i<=n; i++)        {            //cout<<dist[i]<<" "<<have[i]<<endl;            ans+=pow(10.0,dist[i])*have[i];        }        printf("%.2f\n",ans);    }    return 0;}


0 0
原创粉丝点击