codeforces244C. Checkposts

来源:互联网 发布:局域网ip mac扫描软件 编辑:程序博客网 时间:2024/06/05 14:19

强连通分量模板题

/**  Tarjan 算法*  复杂度O(m+n);*/#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <ctime>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#define INF 0x3f3f3f3f#define inf -0x3f3f3f3f#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define mem0(a) memset(a,0,sizeof(a))#define mem1(a) memset(a,-1,sizeof(a))#define mem(a, b) memset(a, b, sizeof(a))typedef long long ll;const int maxn=500001;const int MOD=1e9+7;vector<int>G[maxn];int Low[maxn],Stack[maxn],DFN[maxn],Belong[maxn];//Belong数组的值是1-scc;int Index,top;int a[maxn];int scc;//强连通分量的个数int cost[maxn];bool Instack[maxn];int num[maxn]; //各个强连通分量包含的点的个数,数组编号1-scc//num数组不一定需要,结合实际情况void Tarjan(int u){    int v;    Low[u]=DFN[u]=++Index;    Stack[top++]=u;    Instack[u]=true;    for(int i=0;i<G[u].size();i++){        v=G[u][i];        if(!DFN[v]){            Tarjan(v);            Low[u]=min(Low[u],Low[v]);        }        else if(Instack[v]&&Low[u]>DFN[v])            Low[u]=DFN[v];    }    if(Low[u]==DFN[u]){        scc++;        cost[scc]=INF;        do{            v=Stack[--top];            Instack[v]=false;            Belong[v]=scc;            if(cost[scc]==a[v]){                num[scc]++;            }            else if(cost[scc]>a[v]){                num[scc]=1;                cost[scc]=a[v];            }        }while(v!=u);    }    return ;}void solve(int n){    mem0(DFN);    memset(Instack,false,sizeof(Instack));    mem0(num);    Index=scc=top=0;    for(int i=1;i<=n;i++)        if(!DFN[i])            Tarjan(i);}void init(int n){    for(int i=1;i<=n;i++)        G[i].clear();}int main(){    int n,m;    while(scanf("%d",&n)!=EOF){        init(n);        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        scanf("%d",&m);        int x,y;        for(int i=0;i<m;i++){            scanf("%d%d",&x,&y);            G[x].push_back(y);        }        solve(n);        ll ans1=0,ans2=1;        for(int i=1;i<=scc;i++){            ans1+=cost[i];            ans2=ans2*num[i]%MOD;        }        printf("%I64d %I64d\n",ans1,ans2);    }    return 0;}
0 0
原创粉丝点击