hdu 1827 Summer Holiday tarjan 加缩点

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1827

trajan算法看明白了,不过这道题的做法还是有点不是太懂,看了其他的博客才ac的。

主要就是找连通分量的个数和连通分量的root(入度为零的点),并计算到每个连通分量的最小值。

View Code
  1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <cmath>
5 #include <stack>
6 using namespace std;
7 const int MAX=1005;
8 const int INF=9999999;
9 int DFS[MAX],low[MAX];
10 int N,scc,n,m,vcnt;
11 int head[MAX];
12 int vist[MAX];
13 int dist[MAX];
14 int tt[MAX];
15 int judge[MAX];
16 int mis[MAX];
17 struct ss{
18 int x,y,next;
19 }edge[2050];
20 void init()
21 {
22 memset(DFS,0,sizeof(DFS));
23 memset(low,0,sizeof(low));
24 memset(head,-1,sizeof(head));
25 memset(vist,0,sizeof(vist));
26 memset(dist,0,sizeof(dist));
27 memset(judge,0,sizeof(judge));
28 vcnt=0;
29 N=1;
30 scc=0;
31 }
32 stack<int>S;
33 void tarjan(int u)//求强连通分量
34 {
35 int i,t;
36 DFS[u]=low[u]=++vcnt;
37
38 S.push(u);
39 vist[u]=1;
40 for (i=head[u];i!=-1;i=edge[i].next)
41 {
42 t=edge[i].y;
43 if(!DFS[t])
44 {
45 tarjan(t);
46 if(low[u]>low[t])
47 low[u]=low[t];
48 }
49 else if(vist[t]==1&&low[u]>DFS[t])
50 low[u]=DFS[t];
51 }
52 if(DFS[u]==low[u])
53 {
54 scc++;
55 do {
56 t=S.top();
57 vist[t]=0;
58 dist[t]=scc;
59 S.pop();
60 } while(t!=u);
61 }
62 }
63 int min(int x,int y)
64 {
65 if(x>y)return y;
66 else return x;
67 }
68 int main()
69 {
70 int i,x,y,sum,ma;
71 while (scanf("%d%d",&n,&m)!=EOF)
72 {
73 init();
74 while (!S.empty())
75 {
76 S.pop();
77 }
78 for (i=1;i<=n;i++)
79 {
80 scanf("%d",&tt[i]);
81 }
82 for (i=1;i<=m;i++)
83 {
84 scanf("%d%d",&x,&y);
85 edge[N].y=y;
86 edge[N].x=x;
87 edge[N].next=head[x];
88 head[x]=N++;
89 }
90 for (i=1;i<=n;i++)
91 if(!DFS[i]){
92 tarjan(i);
93 }
94
95 int u,v;
96 for (i=1;i<=m;i++)
97 {
98 u=dist[edge[i].x];
99 v=dist[edge[i].y];
100 if(u==v)continue;
101 judge[v]++;
102 }
103 ma=0;
104 for (i=1;i<=scc;i++)
105 {
106 mis[i]=INF;
107 if(!judge[i])
108 ma++;
109 }
110 for (i=1;i<=n;i++)
111 {
112 mis[dist[i]]=min(mis[dist[i]],tt[i]);
113 }
114 sum=0;
115
116 for (i=1;i<=scc;i++)
117 {
118 if(judge[i]==0)
119 sum+=mis[i];
120 }
121 printf("%d %d\n",ma,sum);
122
123 }
124 return 0;
125 }



posted @ 2012-03-29 14:37  我们一直在努力  阅读(164)  评论(0编辑  收藏  举报