• 2012东北地区赛C题(缩点+bfs)


    数据出水了,直接bfs也能过。

    下面是我写的缩点+bfs的方法。

    View Code
    /*
    Source Code
    Problem: 1003
    Username: 2010201211
    Run Time: 36MS
    Memory: 5188K
    Language:C++
    JudgeStatus: Accepted
    */
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define V 1005
    #define E 1005000
    int n,m,dfn[V],low[V];
    int top,cnt,indexs,ecnt;
    bool instack[V];
    int stack[V],id[V],num[V],in[V],out[V],w[V],vis[V],queue[V],sum[V];
    int map[V][V];
    int head[V];
    struct edge{
        int s,t,cost,next;
    }e[E];
    void addedge(int u,int v){
        e[ecnt].s=u;
        e[ecnt].t=v;
        e[ecnt].next=head[u];
        head[u]=ecnt++;
    }
    void tarjan(int u){
        int v;
        int tmp;
        dfn[u]=low[u]=++indexs;
        instack[u]=true;
        stack[++top]=u;
        for(int k=head[u];k!=-1;k=e[k].next){
            v=e[k].t;
            if(!dfn[v]){
                tarjan(v);
                if(low[v]<low[u])
                    low[u]=low[v];
            }
            else if(instack[v] && dfn[v]<low[u]){
                low[u]=dfn[v];
            }
        }
        if(dfn[u]==low[u]){
            cnt++;
            do{
                tmp=stack[top--];
                instack[tmp]=false;
                id[tmp]=cnt;
                num[cnt]+=w[tmp];
            }
            while(tmp!=u);
        }
    }
    void suodian(){
    
        for(int i=1;i<=n;i++){
            int tmp=id[i];
            for(int k=head[i];k!=-1;k=e[k].next){
                int tmp1=id[e[k].t];
                if(id[i]!=id[e[k].t]){
                    out[tmp]++;
                    in[tmp1]++;
                    map[tmp][tmp1]=1;
                }
            }
        }
        /*cout <<"id:";
        for(int i=1;i<=n;i++){
            printf("%d ",id[i]);
        }
        cout << endl<<"in:";
        for(int i=1;i<=cnt;i++){
            printf("%d ",in[i]);
        }
        cout << endl<<"out:";
        for(int i=1;i<=cnt;i++){
            printf("%d ",out[i]);
        }
        cout << endl<<"num:";
        for(int i=1;i<=cnt;i++){
            printf("%d ",num[i]);
        }
        cout << endl;*/
    }
    void bfs(int u){
        memset(vis,0,sizeof(vis));
        vis[u]=1;
        int v,head=0,tail=0;
        sum[u]+=num[u];
       // cout << sum[u] << endl;
        queue[tail++]=u;
        while(head<tail){
            v=queue[head++];
            for(int i=1;i<=cnt;i++){
                if(map[i][v]==1 && vis[i]==0){
                    vis[i]=1;
                    sum[u]+=num[i];
                    //cout << sum[u] << endl;
                    queue[tail++]=i;
                }
            }
        }
    }
    void findmax(){
        int mmax=-1;
        int mmin=1050;
        for(int i=1;i<=cnt;i++){
            if(out[i]==0){
                bfs(i);
                if(sum[i]>mmax){
                    mmax=sum[i];
                    /*for(int j=1;j<=n;j++){
                        if(id[j]==i && j<mmin){
                            mmin=j;
                        }
                    }*/
                }
            }
        }
        for(int i=1;i<=cnt;i++){
            if(out[i]==0){
                if(sum[i]==mmax){
                    for(int j=1;j<=n;j++){
                        if(id[j]==i && j<mmin){
                            mmin=j;
                        }
                    }
                }
            }
        }
        /*for(int i=1;i<=cnt;i++){
            printf("%d ",sum[i]);
        }
        cout << endl;*/
        printf("%d\n",mmin);
    }
    void solve(){
    
        top=cnt=indexs=0;
        memset(dfn,0,sizeof(dfn));
        memset(num,0,sizeof(num));
        memset(sum,0,sizeof(sum));
        memset(map,0,sizeof(map));
        memset(id,0,sizeof(id));
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        for(int i=1;i<=n;i++){
            if(!dfn[i])
                tarjan(i);
    
        }
        suodian();
        findmax();
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int a,b;
        while(scanf("%d%d",&n,&m)!=EOF){
            for(int i=1;i<=n;i++){
                scanf("%d",&w[i]);
            }
            ecnt=0;
            memset(head,-1,sizeof(head));
            for(int i=1;i<=m;i++){
                scanf("%d%d",&a,&b);
                addedge(b,a);
            }
            solve();
        }
        return 0;
    }
  • 相关阅读:
    软件的分解-编程语言自带分解功能
    面向接口编程定义了软件的生长方式
    软件开发的分:分离、分解、分类
    软件开发的分离之术-软件易变性的应对之道
    软件的本质
    软件开发的核心问题-三次转换
    没有银弹-软件工程中的根本和次要问题
    软件复杂性的通俗理解
    软件的复杂性与构造定律
    软件复杂性
  • 原文地址:https://www.cnblogs.com/markliu/p/2571832.html
Copyright © 2020-2023  润新知