zoukankan      html  css  js  c++  java
  • HDU 3072 Intelligence System(强连通分量)

     

    题目大意

     

    给了一个含有 n(0<n<=50000) 个节点的有向图,图中的两点之间的通信时要付出代价的(经过的边权之和),但是如果这两个点之间相互可达,代价为 0

    问,从给定的节点向其他所有的点通信,所花费的最小代价是多少?

     

    做法分析

     

    先对原图缩点,形成一个 DAG,给的那个定点显然是 DAG 中入度为 0 的点,并且入度为 0 的点肯定只有一个(根据题目的意思)

    每个顶点(除了那个定点)必定只有一个入点,那么,对于每个顶点,完全可以选择代价最小的那条入点,贪心的找即可

     

    参考代码

     

    HDU 3072
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <stack>
     5 
     6 using namespace std;
     7 
     8 const int N=50006;
     9 
    10 struct Edge
    11 {
    12     int u, val, next;
    13     Edge() {}
    14     Edge(int a, int b, int c)
    15     {
    16         u=a, val=b, next=c;
    17     }
    18 } edge[100006];
    19 int head[N], tot;
    20 int n, m;
    21 
    22 void add_edge(int st, int en, int val)
    23 {
    24     edge[tot]=Edge(en, val, head[st]);
    25     head[st]=tot++;
    26 }
    27 
    28 int dfn[N], low[N], T, ind, id[N];
    29 bool vs[N];
    30 stack<int> S;
    31 
    32 void tarjan(int u)
    33 {
    34     S.push(u), vs[u]=true;
    35     dfn[u]=low[u]=T++;
    36     for(int e=head[u]; e!=-1; e=edge[e].next)
    37     {
    38         int v=edge[e].u;
    39         if(dfn[v]==-1)
    40         {
    41             tarjan(v);
    42             low[u]=min(low[u], low[v]);
    43         }
    44         else if(vs[v] && low[u]>dfn[v]) low[u]=dfn[v];
    45     }
    46     if(low[u]==dfn[u])
    47     {
    48         for(int v; 1; )
    49         {
    50             v=S.top();
    51             id[v]=ind;
    52             vs[v]=false, S.pop();
    53             if(v==u) break;
    54         }
    55         ind++;
    56     }
    57 }
    58 
    59 int in[N];
    60 
    61 int main()
    62 {
    63     while(scanf("%d%d", &n, &m)!=EOF)
    64     {
    65         memset(head, -1, sizeof head);
    66         tot=0;
    67         for(int i=0, a, b, c; i<m; i++)
    68         {
    69             scanf("%d%d%d", &a, &b, &c);
    70             add_edge(a, b, c);
    71         }
    72         while(!S.empty()) S.pop();
    73         memset(vs, 0, sizeof vs);
    74         memset(dfn, -1, sizeof dfn);
    75         T=ind=0;
    76         for(int i=0; i<n; i++) if(dfn[i]==-1) tarjan(i);
    77         for(int i=0; i<ind; i++) in[i]=0x3fffffff;
    78         for(int i=0; i<n; i++)
    79         {
    80             int u=id[i];
    81             for(int e=head[i]; e!=-1; e=edge[e].next)
    82             {
    83                 int v=id[edge[e].u];
    84                 if(u!=v) in[v]=min(in[v], edge[e].val);
    85             }
    86         }
    87         int ans=0;
    88         for(int i=0; i<ind; i++)
    89         {
    90             if(i==id[0]) continue;
    91             ans+=in[i];
    92         }
    93         printf("%d\n", ans);
    94     }
    95     return 0;
    96 }

    AC通道

    HDU 3072 Intelligence System

  • 相关阅读:
    HDU2026 首字母变大写
    HDU2026 首字母变大写
    Recursive Bubble Sort(递归冒泡排序)
    Recursive Bubble Sort(递归冒泡排序)
    Topological Sorting(拓扑排序)
    Topological Sorting(拓扑排序)
    HDU1870 愚人节的礼物【堆栈+输入输出】
    HDU1870 愚人节的礼物【堆栈+输入输出】
    HDU1233 还是畅通工程
    HDU1233 还是畅通工程
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/2964052.html
Copyright © 2011-2022 走看看