题目大意:有n种物品,每种有相应的价值和数量。现在给m组关系链,组成一张关系网,表示某物品之间相互转换的关系。求已知的物品能获得的最大价值。
思路:如果暴力的话n*m是微微有点超时,所以拓扑排序,时间复杂度是n+m
给出一个转化关系 1->2 2->3 3->4.求出3->4的最优转化或者不转化是自己。2可以转化为3也可以转化为4,或者不转化是自己,2的最优就是不转化,或者转化为3->4的最优。3->4的最优已经算出来了,不用再算一次。
所以拓扑排序后,反向算就能获得最大价值
#include <cstdio>
#include <cstring>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <map>
using namespace std;
const int N=10005;
struct node{
double c;
int to;
};
vector<node>g[N];
double p[N];
double w[N];
int in[N];
int main()
{
int n,m,k;
while(~scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
{
g[i].clear();
in[i]=0;
scanf("%lf%lf",&p[i],&w[i]);
}
scanf("%d",&m);
while(m--)
{
int a,a1;
double b;
scanf("%d%d",&k,&a);
k--;
while(k--)
{
scanf("%lf%d",&b,&a1);
node cur;
cur.to=a,cur.c=b;
g[a1].push_back(cur);
in[a]++;
a=a1;
}
}
queue<int>q;
for(int i=1;i<=n;i++)if(in[i]==0)q.push(i);
double ans=0;
while(!q.empty())
{
int cur=q.front();
q.pop();
ans+=p[cur]*w[cur];
node temp;
for(int i=0;i<g[cur].size();i++)
{
temp=g[cur][i];
p[temp.to]=max(p[temp.to],p[cur]*temp.c);
in[temp.to]--;
if(in[temp.to]==0)q.push(temp.to);
}
}
printf("%.2lf\n",ans);
}
return 0;
}