hdu1827Summer Holiday【tarjan强连通分量解决最小联系费用】

来源:互联网 发布:js弹出消息框自动关闭 编辑:程序博客网 时间:2024/05/17 01:13

1A~·~~~撒花!这比买买买开心多了^-^

思路:既然是强连通分量的题,很容易想到形成的东西是一坨一坨的,哈哈,然后如果某一坨入度为0,那么很不幸,这一坨只能直接被威士忌通知,至于具体通知这一坨中的哪一个,枚举一遍就知道了,最后把话费求和~

感觉强连通分量是图论当中学的最明白的了

/************hdu18272015.11.11358MS 1896K 2169 B************/#include <iostream>#include<cstdio>#include<stack>#include<vector>#include<cstring>#include<algorithm>using namespace std;#define maxn 2020vector<int>G[maxn];int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;stack<int>S;int in0[maxn],out0[maxn];int value[maxn];int cost;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 main(){    int  T,n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        for(int i=0;i<n;i++) G[i].clear();        cost=0;        for(int i=0;i<n;i++) scanf("%d",&value[i]);        for(int i=0;i<m;i++)        {            int u,v;            scanf("%d%d",&u,&v);u--;v--;            G[u].push_back(v);        }        find_scc(n);        for(int i=1;i<=scc_cnt;i++) in0[i]=out0[i]=1;        for(int u=0;u<n;u++)        {            for(int i=0;i<G[u].size();i++)            {                int v=G[u][i];                if(sccno[u]!=sccno[v]) in0[sccno[v]]=out0[sccno[u]]=0;            }        }        int a=0,b=0;        for(int i=1;i<=scc_cnt;i++)        {            if(in0[i])            {                a++;                int maxvalue=0x3f3f3f3f;                for(int j=0;j<n;j++)                {                    if(sccno[j]==i)                    maxvalue=min(maxvalue,value[j]);                }                cost+=maxvalue;            }        }        printf("%d %d\n",a,cost);    }    return 0;}


0 0