zoukankan      html  css  js  c++  java
  • HDU

    题意:

      给出一个N个节点的有向图。图中任意两点进行通信的代价为路径上的边权和。如果两个点能互相到达那么代价为0。问从点0开始向其余所有点通信的最小代价和。保证能向所有点通信。

    题解:

      求出所有的强连通分量,然后进行缩点操作。最后贪心的找出每个点的最小代价,然后求和。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 5e4+10;
    const int inf = 0x3f3f3f3f;
    int n, m;
    struct node {
        int u, v, w;
    }e[maxn<<1];
    vector<int> g[maxn];
    vector<int> rg[maxn];
    vector<int> vs;
    bool vis[maxn];
    int cmp[maxn], in[maxn];
    ll ans;
    void add_edge(int u, int v) {
        g[u].push_back(v);
        rg[v].push_back(u);
    }
    void dfs(int u) {
        vis[u] = true;
        int len = g[u].size();
        for(int i = 0; i < len; i++) {
            int v = g[u][i];
            if(!vis[v]) dfs(v);
        }
        vs.push_back(u);
    }
    void rdfs(int u, int k) {
        vis[u] = true;
        cmp[u] = k;
        int len = rg[u].size();
        for(int i = 0; i < len; i++) {
            int v = rg[u][i];
            if(!vis[v]) rdfs(v, k);
        }
    }
    int scc() {
        memset(vis, 0, sizeof(vis));
        vs.clear();
        for(int u = 0; u < n; u++) {
            if(!vis[u]) dfs(u);
        }
        memset(vis, 0, sizeof(vis));
        int k = 0;
        int len = vs.size();
        for(int i = len-1; i >= 0; i--) {
            int v = vs[i];
            if(!vis[v]) rdfs(v, k++);
        }
        return k;
    }
    int main() {
        while(~scanf("%d%d", &n, &m)) {
            ans = 0;
            for(int i = 0; i < n; i++) {
                g[i].clear();
                rg[i].clear();
            }
            for(int i = 1; i <= m; i++) {
                scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
                add_edge(e[i].u, e[i].v);
            }
            n = scc();
            for(int i = 0; i < n; i++) in[i] = maxn;
            for(int i = 1; i <= m; i++) {
                int u = cmp[e[i].u];
                int v = cmp[e[i].v];
                if(u!=v) in[v] = min(in[v], e[i].w);
            }
            for(int i = 1; i < n; i++) ans += in[i];
            printf("%lld
    ", ans);
        }
    }
    View Code
  • 相关阅读:
    Smobiler实现手机弹窗
    在 ASP.NET Web API 中使用 Attribute 统一处理异常
    VMWare的网络模式说明
    Windows Server2008 IIS通过Nginx实现绑定多个https域名
    Error while Launching activity
    Android 动态渐变按钮
    mysql安装和配置详解以及Navicat连接失败问题
    selenium的基础学习
    使用Pandas.read_csv时出现OSError: Initializing from file failed
    sklearn 机器学习 Pipeline 模板
  • 原文地址:https://www.cnblogs.com/Pneuis/p/8996830.html
Copyright © 2011-2022 走看看