Home  >  Article  >  Web Front-end  >  Codeforces Round #244 (Div. 2)??Checkposts_html/css_WEB-ITnose

Codeforces Round #244 (Div. 2)??Checkposts_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-24 12:05:111031browse

Question link

  • Question meaning:
    Given n points, each point has a directed graph with a weight. Now we need to select some points so that the sum of the weights of these points is the smallest and satisfies: If i can reach j and j can reach i, then i and j can only choose one
  • Analysis:
    Strong Unicom Template question
  • //使用时只更新G完成构图//scc_cnt从1开始计数//pre[]表示点在DFS树中的先序时间戳//lowlink[]表示当前点和后代能追溯到的最早祖先的pre值//sccno[]表示点所在的双连通分量编号//vector<int> G保存每个点相邻的下一个点序号//stack<Edge> S是算法用到的栈const int MAXV = 310000;vector<int> G[MAXV];int pre[MAXV], lowlink[MAXV], sccno[MAXV], dfs_clock, scc_cnt;stack<int> S;void init(int n){    REP(i, n) G[i].clear();}void dfs(int u){    pre[u] = lowlink[u] = ++dfs_clock;    S.push(u);    for(int i = 0; i < G[u].size(); i++)    {        int v = G[u][i];        if(!pre[v])        {            dfs(v);            lowlink[u] = min(lowlink[u], lowlink[v]);        }        else if(!sccno[v])        {            lowlink[u] = min(lowlink[u], pre[v]);        }    }    if(lowlink[u] == pre[u])    {        scc_cnt++;        for(;;)        {            int x = S.top();            S.pop();            sccno[x] = scc_cnt;            if(x == u) break;        }    }}void find_scc(int n){    dfs_clock = scc_cnt = 0;    memset(sccno, 0, sizeof(sccno));    memset(pre, 0, sizeof(pre));    for(int i = 0; i < n; i++)        if(!pre[i]) dfs(i);};int cost[MAXV];vector<int> vt[MAXV];int Min[MAXV];int main(){//    freopen("in.txt", "r", stdin);    int n, e, a, b;    while (~RI(n))    {        init(n);        REP(i, MAXV) vt[i].clear();        CLR(Min, INF);        REP(i, n) RI(cost[i]);        RI(e);        REP(i, e)        {            RII(a, b); a--; b--;            G[a].push_back(b);        }        find_scc(n);        REP(i, n)        {            int no = sccno[i];            vt[no].push_back(i);            Min[no] = min(Min[no], cost[i]);        }        LL v = 0, ans = 1;        REP(i, MAXV)        {            if (vt[i].size() > 0)            {                int cnt = 0;                REP(j, vt[i].size())                {                    if (cost[vt[i][j]] == Min[i]) cnt++;                }                ans *= cnt;                ans %= MOD;                v += Min[i];            }        }        cout << v << ' ' << ans << endl;    }    return 0;}



    Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn