• hdu 1827强连通分量


    原题链接

    题意是有一堆人,和若干关系(单向),你假如选择了一个人,那么其他可以传递的都不需要花费就可以得到。。问最小花费和最少选择人数。。


    是一个求强连通的题目,因为如果我们把强连通分量缩点了以后,那么其实就是要把入度为0的都选了就可以,注意如果入度为0的是一个缩点就再枚举找一下里面最小的。。


    接下来就是很显然了,这里套用kuangbin的模板。。第一次做强连通,没有想到缩点,用了个奇怪的姿势水过。。。后来想了想应该是错误的?大概是数据比较弱。


    ac代码(可能有错误,主要练习一下 tarjan。。。


    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    using namespace std;
    int n,m,a,b;
    const int MAXN = 1005;
    const int MAXM = 2005;
    vector<int> E[MAXN];
    struct Edge{
        int to,next;
    } edge[MAXM];
    int head[MAXN],tot;
    int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];
    int Index,top,scc;
    bool Instack[MAXN];
    int num[MAXN];
    void addedge(int u,int v){
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    void Tarjan(int u){
        int v;
        Low[u] = DFN[u] = ++Index;
        Stack[top++] = u;
        Instack[u] = true;
        for(int i = head[u]; i != -1; i = edge[i].next){
            v = edge[i].to;
            if( !DFN[v] ){
                Tarjan(v);
                if( Low[u] > Low[v] )Low[u] = Low[v];
            }
            else if(Instack[v] && Low[u] > DFN[v])    Low[u] = DFN[v];
        }
        if(Low[u] == DFN[u]){
            scc++;
            do{
                v = Stack[--top];
                Instack[v] = false;
                Belong[v] = scc;
                num[scc]++;
            }
            while( v != u);
        }
    }
    void solve(int N){
        memset(DFN,0,sizeof(DFN));
        memset(Instack,false,sizeof(Instack));
        memset(num,0,sizeof(num));
        Index = scc = top = 0;
        for(int i = 1; i <= N; i++)   if(!DFN[i])    Tarjan(i);
    }
    void init(){
        tot = 0;
        memset(head,-1,sizeof(head));
    }
    
    int arr[MAXN];
    int vis[MAXN];
    vector<int> be[MAXN];
    pair<int,int> in[MAXN];
    void dfs(int x){
        vis[x]=1;
        for(int i=0;i<E[x].size();i++){
            if(!vis[E[x][i]])
                dfs(E[x][i]);
        }
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            init();
            memset(in,0,sizeof(in));
            memset(vis,0,sizeof(vis));
            for(int i=0;i<=n;i++) E[i].clear();
            for(int i=0;i<=n;i++) be[i].clear();
            for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
            for(int i=1;i<=n;i++) in[i].second=i;
            for(int i=0;i<m;i++){
                scanf("%d%d",&a,&b);
                addedge(a,b);
                E[a].push_back(b);
                ++in[b].first;
            }
            solve(n);
            sort(in+1,in+n+1);
            int ans=0,cnt=0,ad=0;
            for(int i=1;i<=n;i++){
                be[Belong[i]].push_back(i);
            }
            for(int i=1;i<=n;i++){
                if(vis[in[i].second]==1||(in[i].first!=0&&num[Belong[in[i].second]]==1))
                    continue;
                ++cnt;
                ad=arr[in[i].second];
                for(int j=0;j<be[Belong[in[i].second]].size();j++){
                    ad=min(ad,arr[be[Belong[in[i].second]][j]]);
                }
                ans+=ad;
                dfs(in[i].second);
            }
            printf("%d %d
    ",cnt,ans);
        }
        return 0;
    }
    




  • 相关阅读:
    [NOIP2013]华容道
    [随笔]冲NOIP一等奖。。
    [NOIP2015]联合权值
    [随笔]我回来啦!
    [考试]20151105
    [知识点]最近公共祖先LCA
    [BZOJ3751/NOIP2014]解方程
    [旧版][知识点]字符串Hash
    NOIP2016题解
    NOIP2016游记
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672563.html
Copyright © 2020-2023  润新知