CF 427C Checkposts Tarjan

来源:互联网 发布:淘宝双12页面怎么设置 编辑:程序博客网 时间:2024/05/16 17:05

求每个强连通分量里的最小支出和个数。

#include<iostream>#include<cstdio>#include<vector>using namespace std;const int N=100005,MOD=1e9+7;int cost[N];int Stack[N],top=0;bool inStack[N];int DFN[N],Low[N],Index=0;vector<int> Edge[N];long long sum=0,ans=1;void Tarjan(int u){int v;DFN[u]=Low[u]=++Index;inStack[u]=true;Stack[++top]=u;for(int e=0;e<Edge[u].size();e++){v=Edge[u][e];if(!DFN[v]){Tarjan(v);Low[u]=min(Low[u],Low[v]);}else if(inStack[v])Low[u]=min(Low[u],DFN[v]);}if(DFN[u]==Low[u]){int x=0,y=MOD;do{v=Stack[top--];inStack[v]=false;if(cost[v]<y) x=1,y=cost[v];//求强连通里最小支出else if(cost[v]==y) x++;//以及个数}while(u!=v);sum+=y;ans=(ans*x)%MOD;}}int main(){int n,m,x,y;cin>>n;for(int i=1;i<=n;i++)cin>>cost[i];cin>>m;for(int i=0;i<m;i++){cin>>x>>y;Edge[x].push_back(y);}for(int i=1;i<=n;i++){if(!DFN[i])Tarjan(i);}cout<<sum<<" "<<ans<<endl;return 0;}


0 0