想了半天,弄了个类似拓扑排序的做法,用入度为0的点去更新别的点 然后就可以愉快的转移状态了 不知道思路对不对QAQ
#include<iostream>
#include<queue>
#include<cstdio>
using namespace std;
long long n,f[1005],c[1005],w[1005],h[1005]
,in[1005];//ci记录节点i的方案数 fi记录购买i药水的最小值 in[i]记录i节点的入度,wi记录i号药水的价格,h[i]是链式前向星的头数组
int tot;
struct edge{
int u2,v,nex;
}e[1000005];
queue < int >q;
void add(int u1,int u2,int v){
e[++tot].u2=u2;
e[tot].v=v;
e[tot].nex=h[u1];
h[u1]=tot;
return;
}
void initialize(){//初始化c和f数组
for(int i=0;i<n;i++){
f[i]=w[i];
c[i]=1;
}
return;
}
int main(){
cin>>n;
for(int i=0;i<n;i++)cin>>w[i];
{
int u1;
while(cin>>u1){
int u2,v;
cin>>u2>>v;
add(u1,u2,v);
in[v]++;
}
}
initialize();
for(int i=0;i<n;i++)if(!in[i])q.push(i);
while(!q.empty()){
int u1=q.front();
q.pop();
for(int i=h[u1];i;i=e[i].nex){
int u2=e[i].u2,v=e[i].v;
if(!in[u1]&&!in[u2]){
in[v]--;
if(!in[v])q.push(v);
}
if(f[v]>f[u1]+f[u2]){
f[v]=f[u1]+f[u2];
c[v]=c[u1]*c[u2];
}
else if(f[v]==f[u1]+f[u2]){
c[v]+=c[u1]*c[u2];
}
}
}
cout<<f[0]<<" "<<c[0];
return 0;
}