hdu1827 Summer Holiday(scc应用)

来源:互联网 发布:有域名了怎么建立网站 编辑:程序博客网 时间:2024/06/05 02:26

因为联系是单向的,且具有传递性,所以一个边强连通分量里面最多只需要通知一个人,那么就取代价最小的那个。然后就缩成DAG图,找入度为0的点就好了。

const int maxn = 1001;int head[maxn], pnt[maxn<<2], nxt[maxn<<2], ecnt;int dfn[maxn], low[maxn], depth;int indeg[maxn];int Min[maxn];int belong[maxn], block;int cost[maxn];bool mark[maxn];stack<int> st;int n, m;void tarjan(int u) {    dfn[u] = low[u] = ++depth;    st.push(u);mark[u] = true;    for (int i = head[u];~i;i = nxt[i]) {        int v = pnt[i];        if (dfn[v] == -1) {            tarjan(v);            low[u] = min(low[u], low[v]);        }else if (mark[v]) low[u] = min(low[u], dfn[v]);    }    if (dfn[u] == low[u]) {        block++;        Min[block] = INF;        while(true) {            int x = st.top();            st.pop();            mark[x] = false;            Min[block] = min(Min[block], cost[x]);            belong[x] = block;            if (x == u) break;        }    }}void addedge(int u,int v) {    pnt[ecnt] = v, nxt[ecnt] = head[u], head[u] = ecnt++;}int main(int argc, const char * argv[]){        freopen("in.txt","r",stdin);    // freopen("out.txt","w",stdout);    // clock_t _ = clock();    while(~scanf("%d%d", &n, &m)) {        memset(head, -1,sizeof head), ecnt = 0;        memset(dfn, -1,sizeof dfn), depth = block = 0;        for (int i = 1;i <= n;++i)            scanf("%d", &cost[i]);        int u, v;        while(m--) {            scanf("%d%d", &u, &v);            addedge(u, v);        }        for (int i = 1;i <= n;++i)            if (dfn[i] == -1) tarjan(i);        int MinNum = 0, MinCost = 0;        memset(indeg, 0,sizeof indeg);        for (int i = 1;i <= n;++i) {            for (int j = head[i];~j;j = nxt[j]) {                u = i, v = pnt[j];                if (belong[u] != belong[v])                    indeg[belong[v]]++;            }        }        for (int i = 1;i <= block;++i)            if (indeg[i] == 0) {                MinNum++;                MinCost += Min[i];            }        printf("%d %d\n", MinNum, MinCost);    }    // printf("\nTime cost: %.2fs\n", 1.0 * (clock() - _) / CLOCKS_PER_SEC);    return 0;}
0 0