HDU ACM 1827 Summer Holiday(图的强连通+缩点)
http://acm.hdu.edu.cn/showproblem.php?pid=1827
思路:用Tarjan算法求出各个强连通分支,同一个强连通分支抽象成一点
1 #include <iostream> 2 #include <vector> 3 #include <stack> 4 using namespace std; 5 const int maxn = 1000 + 10; 6 const int maxm = 2000 + 10; 7 struct Node{ 8 int cost; 9 int dfn; 10 int low; 11 int belong; 12 }; 13 Node Call[maxn]; 14 vector <int> v[maxn]; 15 stack <int> s; 16 int time; 17 int instack[maxn]; 18 int indegree[maxn]; 19 void Tarjan(int u){ 20 Call[u].dfn = Call[u].low = ++time; 21 s.push(u); 22 instack[u] = 1; 23 int i; 24 for(i=0;i<v[u].size();i++){ 25 if(Call[v[u][i]].dfn == 0){ 26 Tarjan(v[u][i]); 27 Call[u].low = min(Call[u].low,Call[v[u][i]].low); 28 } 29 else{ 30 if(instack[v[u][i]]){ 31 Call[u].low = min(Call[u].low,Call[v[u][i]].dfn); 32 } 33 } 34 } 35 if(Call[u].low == Call[u].dfn){ 36 int x = s.top(); 37 s.pop(); 38 instack[x] = 0; 39 Call[x].belong = u; 40 Call[u].cost = min(Call[u].cost,Call[x].cost); 41 while(x != u){ 42 x = s.top(); 43 s.pop(); 44 instack[x] = 0; 45 Call[x].belong = u; 46 Call[u].cost = min(Call[u].cost,Call[x].cost); 47 } 48 } 49 } 50 void Init(){ 51 while(!s.empty()){ 52 s.pop(); 53 } 54 int i; 55 for(i=0;i<maxn;i++){ 56 v[i].clear(); 57 } 58 memset(Call,0,sizeof(Call)); 59 memset(instack,0,sizeof(instack)); 60 memset(indegree,0,sizeof(indegree)); 61 } 62 int main(){ 63 int n,m; 64 while(cin>>n>>m){ 65 Init(); 66 int i,j; 67 for(i=1;i<=n;i++){ 68 cin>>Call[i].cost; 69 } 70 int a,b; 71 for(i=1;i<=m;i++){ 72 scanf("%d%d",&a,&b); 73 v[a].push_back(b); 74 } 75 time = 0; 76 for(i=1;i<=n;i++){ 77 if(!Call[i].dfn){ 78 Tarjan(i); 79 } 80 } 81 int used[maxn] = {0}; 82 for(i=1;i<=n;i++){ 83 for(j=0;j<v[i].size();j++){ 84 if(Call[i].belong != Call[v[i][j]].belong){ 85 indegree[Call[v[i][j]].belong]++; 86 } 87 } 88 } 89 int sum = 0; 90 int num = 0; 91 for(i=1;i<=n;i++){ 92 if(!used[Call[i].belong] && indegree[Call[i].belong] == 0 ){ 93 used[Call[i].belong] = 1; 94 sum++; 95 num += Call[Call[i].belong].cost; 96 } 97 } 98 cout<<sum<<" "<<num<<endl; 99 } 100 return 0; 101 } 102 /* 103 Sample Input 104 12 16 105 2 2 2 2 2 2 2 2 2 2 2 2 106 1 3 107 3 2 108 2 1 109 3 4 110 2 4 111 3 5 112 5 4 113 4 6 114 6 4 115 7 4 116 7 12 117 7 8 118 8 7 119 8 9 120 10 9 121 11 10 122 Sample Output 123 3 6 124 */