MemoryGarden's Blog

努力 -----------大能猫

C++博客 首页 新随笔 联系 聚合 管理
  118 Posts :: 11 Stories :: 20 Comments :: 0 Trackbacks
from roba

找出强联通分量,然后求出缩点图,找出缩点图内出度为0的点内的原顶点最小的cost值累加

(关于强联通分量前面有文章介绍)

#include <stdio.h>
#include 
<string.h>
const int N = 10001;
const int M = 200001;
struct e{
    
int v;
    e
* next;
};
e
* link[N], edge[M], *tlink[N], tedge[M];
int n, m, cost[N], el, tel, f[N], time, belon[N], degree[N], s[N], ans[N];
bool judge[N], zero[N];
void dfs(int v){
    
int i;e* l = link[v];judge[v] = true;
    
while(l){
        
if(!judge[l->v])dfs(l->v);
        l 
= l->next;
    }f[v] 
= time++;
}
void tdfs(int v, int p){
    
int i;e* l = tlink[v];judge[v] = true;belon[v] = p;
    
while(l){
        
if(!judge[l->v])tdfs(l->v, p);
        l 
= l->next;
    }
}
int main(){
    freopen(
"2233.in""r", stdin);
    freopen(
"2233.out""w", stdout);
    
int i, j, u, v, fl, out;e* l;
    
while(scanf("%d%d"&n, &m), m || n){
        
for(i = time = 0; i < n; i++){tlink[i] = link[i] = NULL;judge[i] = degree[i] = zero[i] = 0;ans[i] = 0x7fffffff;}
        
for(i = 0; i < n; i++)scanf("%d"&cost[i]);
        
for(el = tel = 0, i = 0; i < m; i++){
            scanf(
"%d%d"&u, &v);u--;v--;
            edge[el].v 
= v;edge[el].next = link[u];link[u] = &edge[el++];
            tedge[tel].v 
= u;tedge[tel].next = tlink[v];tlink[v] = &tedge[tel++];
        }
        
for(i = 0; i < n; i++)if(!judge[i])dfs(i);
        
for(i = 0; i < n; i++)s[f[i]] = i;
        memset(judge, 
0sizeof(judge));fl = 0;
        
for(i = n - 1; i >= 0; i--){
            
if(!judge[s[i]]){
                tdfs(s[i], fl
++);
            }
        }
        
for(i = 0; i < n; i++){
            l 
= link[i];
            
while(l){
                
if(belon[i] != belon[l->v])degree[belon[l->v]]++;
                l 
= l->next;
            }
        }
        
for(i = 0; i < fl; i++){if(!degree[i]){zero[i] = true;}}
        
for(i = 0; i < n; i++){
            
if(zero[belon[i]]){
                
if(cost[i] < ans[belon[i]])ans[belon[i]] = cost[i];
            }
        }
out = 0;
        
for(i = 0; i < n; i++){
            
if(zero[i])out += ans[i];
        }
        printf(
"%d\n"out);
    }
    
return 0;
}


posted on 2009-10-08 00:54 memorygarden 阅读(269) 评论(0)  编辑 收藏 引用 所属分类: 报告

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理