poj 3160

#include<iostream>
#include<fstream>

using namespace std;

struct e{
    int data;
    e *next;
};

e edge[30001],edge1[30001];

int n,m;

void add(int s,int t)
{
    e *p=new e;
    p->data=t;
    p->next=edge[s].next;
    edge[s].next=p;
}

int v[30001],dfn[30001],low[30001],top,scc[30001],sta[30001];
int total;
int index;
int a[30001];
int value[30001];

void dfs(int s){
    int i,j,k;
    dfn[s]=low[s]=++index;
    sta[++top]=s;
    v[s]=1;
    e *p=edge[s].next;
    while(p)
    {
        if(dfn[p->data]==0)
        {
            dfs(p->data);
            low[s]=min(low[s],low[p->data]);
        }
        else
            if(v[p->data])
                low[s]=min(low[s],dfn[p->data]);
        p=p->next;
    }
    if(low[s]==dfn[s])
    {
        total++;
        value[total]=0;
        do{
            i=sta[top--];
            scc[i]=total;
            v[i]=0;
            if(a[i]>0)
                value[total]+=a[i];
        }while(i!=s);
    }
}

int dp[30001];

int in[30001];


void dfs1(int s){
    dp[s]=0;
    e *p=edge1[s].next;
    while(p)
    {
        dfs1(p->data);
        dp[s]=max(dp[s],dp[p->data]);
        p=p->next;
    }
    dp[s]+=value[s];
}

void solve(){
    int i,j,k;
    memset(dfn,0,sizeof(dfn));
    index=0;top=0;total=0;
    for(i=1;i<=n;i++)
        if(dfn[i]==0)
        {
            dfs(i);
        }
    for(i=1;i<=total;i++)
        edge1[i].next=0;
    memset(in,0,sizeof(in));

    for(i=1;i<=n;i++)
    {
        e *p=edge[i].next;
        while(p)
        {
            if(scc[p->data]!=scc[i])
            {
                e *q=new e;
                q->data=scc[p->data];
                q->next=edge1[scc[i]].next;
                edge1[scc[i]].next=q;
                in[scc[p->data]]++;
            }

            p=p->next;
        }
    }
    int ans=0;
    for(i=1;i<=total;i++)
        if(in[i]==0)
        {
            dfs1(i);
            ans=max(ans,dp[i]);
        }
    cout<<ans<<endl;
}

void read(){
//    ifstream cin("in.txt");
    int i,j,k,s,t;
    while(cin>>n>>m)
    {
        for(i=1;i<=n;i++)
            edge[i].next=0;
        for(i=1;i<=n;i++)
            cin>>a[i];
        for(i=1;i<=m;i++)
        {
            cin>>s>>t;
            add(s+1,t+1);
        }
        solve();
    }

}

int main(){
    read();
    return 0;
}

posted on 2011-05-30 10:33  宇宙吾心  阅读(402)  评论(0)    收藏  举报

导航