zoukankan      html  css  js  c++  java
  • HDU

    <题目链接>

    题目大意:

    听说lcy帮大家预定了新马泰7日游,Wiskey真是高兴的夜不能寐啊,他想着得快点把这消息告诉大家,虽然他手上有所有人的联系方式,但是一个一个联系过去实在太耗时间和电话费了。他知道其他人也有一些别人的联系方式,这样他可以通知其他人,再让其他人帮忙通知一下别人。你能帮Wiskey计算出至少要通知多少人,至少得花多少电话费就能让所有人都被通知到吗? 

    解题分析:

    强连通缩点,再将所有入度为0的强连通分量中最小的价值相加即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define pb push_back
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(a,b) memset(a,b,sizeof(a))
    const int N = 1e3+10,M = 2e3+10;
    int n,m,tot,cnt,scc,top;
    int val[N],instk[N],stk[N],dfn[N],low[N],ind[N],outd[N],belong[N],head[N];
    struct Edge{
        int to,next;
    }edge[M];
    vector<int>G[N];
    void init(){
        rep(i,0,n)G[i].clear();
        tot=cnt=scc=top=0;
        clr(instk,0);clr(stk,0);clr(dfn,0);clr(low,0);clr(ind,0);clr(outd,0);clr(belong,0),clr(head,-1);
    }
    void addedge(int u,int v){
        edge[++cnt].to=v,edge[cnt].next=head[u];
        head[u]=cnt;
    }
    void Tarjan(int u){
        dfn[u]=low[u]=++tot;
        stk[++top]=u;instk[u]=1;
        for(int i=head[u];~i;i=edge[i].next){
            int v=edge[i].to;
            if(!dfn[v]){
                Tarjan(v);
                low[u]=min(low[u],low[v]);
            }else if(instk[v])low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u]){
            scc++;
            while(true){
                int v=stk[top--];
                instk[v]=0;
                belong[v]=scc;
                G[scc].pb(v);
                if(v==u)break;
            }
        }
    }
    int main(){
        while(scanf("%d%d",&n,&m)!=EOF){
            init();
            rep(i,1,n)scanf("%d",&val[i]);
            rep(i,1,m){
                int u,v;scanf("%d%d",&u,&v);
                addedge(u,v);
            }
            rep(i,1,n)
                if(!dfn[i])Tarjan(i);
            rep(u,1,n) for(int i=head[u];~i;i=edge[i].next){
                int v=edge[i].to;
                if(belong[u]!=belong[v])
                    ind[belong[v]]++,outd[belong[u]]++;
            }
            int ans=0,res=0;
            rep(i,1,scc) if(!ind[i]){
                int mn=1e9;
                rep(j,0,G[i].size()-1){      //遍历该连通块中的所有元素,寻找价值最小的
                    int v=G[i][j];
                    mn=min(mn,val[v]);
                }
                res++;
                ans+=mn;
            }
            printf("%d %d
    ",res,ans);
        }
    }
  • 相关阅读:
    php面试题
    php最基本的缓存之一页面缓存
    原生PHP生成验证码
    原生PHP实现上传大图片与缩略图
    PHP实现连接数据库下载与导入csv格式文件
    ScrollTop火狐谷歌不兼容
    今天学的是 HTML基本元素、基本语法元素特点等,就发图片吧。
    第三天的学习知识HTML5常用的重要单词
    第二天学习了设计方面的知识
    HTLM5第一天的内容
  • 原文地址:https://www.cnblogs.com/00isok/p/10765315.html
Copyright © 2011-2022 走看看