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

 

 

 

posted @ 2013-03-17 00:20  jianzhang.zj  阅读(805)  评论(0编辑  收藏  举报