HDU 1827 Sunmmer Holiday

To see a World in a Grain of Sand
And a Heaven in a Wild Flower,
Hold Infinity in the palm of your hand
And Eternity in an hour.
                  —— William Blake

听说lcy帮大家预定了新马泰7日游,Wiskey真是高兴的夜不能寐啊,他想着得快点把这消息告诉大家,虽然他手上有所有人的联系

方式,但是一个一个联系过去实在太耗时间和电话费了。他知道其他人也有一些别人的联系方式,这样他可以通知其他人,再让其

他人帮忙通知一下别人。你能帮Wiskey计算出至少要通知多少人,至少得花多少电话费就能让所有人都被通知到吗?

Input

多组测试数组,以EOF结束。
第一行两个整数N和M(1<=N<=1000, 1<=M<=2000),表示人数和联系对数。
接下一行有N个整数,表示Wiskey联系第i个人的电话费用。
接着有M行,每行有两个整数X,Y,表示X能联系到Y,但是不表示Y也能联系X。
Output

输出最小联系人数和最小花费。
每个CASE输出答案一行。
Sample Input

12 16
2 2 2 2 2 2 2 2 2 2 2 2 
1 3
3 2
2 1
3 4
2 4
3 5
5 4
4 6
6 4
7 4
7 12
7 8
8 7
8 9
10 9
11 10

Sample Output

3 6

标签:强连通 Tarjan算法


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<stack>
 7 using namespace std;
 8 #define MAXN 1111
 9 #define inf 1<<30
10 vector<int>vet[MAXN];
11 vector<int>map[MAXN];
12 stack<int>S;      //用栈实现
13 bool mark[MAXN];
14 int color[MAXN];
15 int to[MAXN];//入度
16 int dfn[MAXN],low[MAXN];
17 int n,m,cnt,_count;
18 int cost[MAXN];
19 
20 void Tarjan(int u){     //Tarjan 算法
21    dfn[u]=low[u]=++cnt;
22    mark[u]=true;
23    S.push(u);
24    for(int i=0;i<vet[u].size();i++){
25       int v=vet[u][i];
26       if(dfn[v]==0){
27          Tarjan(v);
28          low[u]=min(low[u],low[v]);
29       }else if(mark[v]){
30          low[u]=min(low[u],dfn[v]);
31       }
32    }
33    if(low[u]==dfn[u]){
34       int v;
35       _count++;
36       do{
37          v=S.top();
38          S.pop();
39          mark[v]=false;
40          color[v]=_count;
41       }while(u!=v);
42    }
43 }
44 
45 int Solve(int u){
46    int MIN=inf;
47    for(int i=1;i<=n;i++){
48       if(color[i]==u&&cost[i]<MIN){
49          MIN=cost[i];
50       }
51    }
52    return MIN;
53 }
54 
55 
56 int main(){
57    int u,v,ans,count;
58    while(~scanf("%d%d",&n,&m)){
59       for(int i=1;i<=n;i++){ vet[i].clear();map[i].clear(); }
60       for(int i=1;i<=n;i++)scanf("%d",&cost[i]);
61       for(int i=1;i<=m;i++){
62          scanf("%d%d",&u,&v);
63          vet[u].push_back(v);
64       }
65       memset(mark,false,sizeof(mark));
66       memset(dfn,0,sizeof(dfn));
67       memset(low,0,sizeof(low));
68       memset(color,0,sizeof(color));
69       memset(to,0,sizeof(to));
70       _count=cnt=0;
71       for(int i=1;i<=n;i++){
72          if(dfn[i]==0)Tarjan(i);
73       }
74       for(int i=1;i<=n;i++){
75          for(int j=0;j<vet[i].size();j++){
76             if(color[i]!=color[vet[i][j]]){
77                map[color[i]].push_back(color[vet[i][j]]);
78                to[color[vet[i][j]]]++;
79             }
80          }
81       }
82       count=ans=0;
83       for(int i=1;i<=_count;i++){
84          if(to[i]==0){
85             count++;
86             ans+=Solve(i);
87          }
88       }
89       printf("%d %d\n",count,ans);
90    }
91    return 0;
92 }





猜你喜欢

转载自www.cnblogs.com/linda-/p/13381851.html
今日推荐