• poj 3592 缩点+SPFA


    题意:给出一个矩阵,其中#代表墙,不可走,0-9代表权值,*代表可以选择传送。求从0,0点开始出发能获得最大权值。

    思路:因为*的出现会有环的情况,先建图连边,将环进行Tarjan缩点,之后再从0,0用SPFA找最长路就行了。

    麻烦的地方在于建图,还有各种错

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define MAXN 1605
    #define MAXM 1605*1605
    #define inf 10000000
    int map[MAXN][MAXN],DFN[MAXN],Low[MAXN],vis[MAXN];
    int stack[MAXM],instack[MAXN],Belong[MAXN],a[MAXN],b[MAXN];
    int que[1605*MAXN],sign[1605*MAXN],dis[1605*MAXN],head[1605*MAXN],val[1605*MAXN];
    int G[MAXN][MAXN];
    char g[50][50];
    int kt,n,m,count1,scnt,top,tot;
    struct Edge
    {
        int to,next;
    }edge[MAXM];
    void addedge(int v,int w)
    {
        edge[tot].to=w;
        edge[tot].next=head[v];
        head[v]=tot++;
    }
    void SPFA(int s)
    {
        memset(sign,false,sizeof(sign));
        for(int i=1;i<=scnt;i++)
        {
            dis[i]=0;
        }
        int l,r;
        l=r=0;
        que[r++]=s;
        sign[s]=true;
        dis[s]=val[s];
        while(l!=r)
        {
            int v=que[l++];
            sign[v]=true;
            for(int i=head[v];i!=-1;i=edge[i].next)
            {
                int j=edge[i].to;
                if(dis[j]<=dis[v]+val[j])
                {
                    dis[j]=dis[v]+val[j];
                    if(!sign[j])
                    {
                        sign[j]=true;
                        que[r++]=j;
                    }
                }
            }
            sign[v]=false;
        }
    }
    void Tarjan(int v)
    {
        instack[v]=1;
        stack[top++]=v;
        DFN[v]=Low[v]=++count1;
        for(int i=0;i<n*m;i++)
        {
            if(map[v][i]==1)
            {
                if(!DFN[i])
                {
                    Tarjan(i);
                    Low[v]=min(Low[v],Low[i]);
                }
                else if(instack[i]==1)
                {
                    Low[v]=min(Low[v],DFN[i]);
                }
            }
        }
        int t;
        if(DFN[v]==Low[v])
        {
            scnt++;
            do
            {
                t=stack[--top];
                instack[t]=0;
                Belong[t]=scnt;
            }while(t!=v);
        }
    }
    void dfs(int x,int y)
    {
        vis[x*m+y]=1;
        if(g[x][y]=='#')
            return ;
    
        if(g[x][y]>='a'&&g[x][y]<='a'+kt)
        {
            int t=g[x][y]-'a';
            if(!map[x*m+y][a[t]*m+b[t]]&&x*m+y!=a[t]*m+b[t])
            {
                map[x*m+y][a[t]*m+b[t]]=1;
                if(!vis[a[t]*m+b[t]])
                dfs(a[t],b[t]);
            }
        }
        if(x+1<n&&g[x+1][y]!='#')
        {
            if(!map[x*m+y][(x+1)*m+y])
            {
                map[x*m+y][(x+1)*m+y]=1;
                if(!vis[(x+1)*m+y])dfs(x+1,y);
            }
        }
        if(y+1<m&&g[x][y+1]!='#')
        {
    
            if(!map[x*m+y][x*m+y+1])
            {
                map[x*m+y][x*m+y+1]=1;
                if(!vis[x*m+y+1])dfs(x,y+1);
            }
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(g,'',sizeof(g));
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++)
            {
                scanf("%s",g[i]);
            }
            kt=0;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    if(g[i][j]=='*')
                        {
                            kt++;
                            g[i][j]='a'+kt;
                        }
                }
            }
            for(int i=1;i<=kt;i++)
            {
                scanf("%d%d",&a[i],&b[i]);
            }
            memset(map,0,sizeof(map));
            memset(vis,0,sizeof(vis));
            dfs(0,0);
            memset(DFN,0,sizeof(DFN));
            memset(instack,0,sizeof(instack));
            memset(stack,0,sizeof(stack));
            memset(Low,0,sizeof(Low));
            memset(Belong,0,sizeof(Belong));
            count1=scnt=top=0;
            Tarjan(0);
            memset(val,0,sizeof(val));
            for(int i=0;i<n*m;i++)
            {
                if(g[i/m][i%m]<='9'&&g[i/m][i%m]>='0')
                {
                    val[Belong[i]]+=g[i/m][i%m]-'0';
                }
            }
            tot=0;
            memset(head,-1,sizeof(head));
            memset(G,0,sizeof(G));
            for(int i=0;i<n*m;i++)
            {
                for(int j=0;j<n*m;j++)
                {
                    if(map[i][j]&&Belong[i]!=Belong[j])
                    {
                        if(!G[Belong[i]][Belong[j]])
                        {
                            addedge(Belong[i],Belong[j]);
                            G[Belong[i]][Belong[j]]=1;
                            //cout<<Belong[i]<<','<<Belong[j]<<endl;
                        }
    
                    }
                }
                //cout<<Belong[i]<<' ';
            }
            SPFA(Belong[0]);
            int ans=0;
            for(int i=1;i<=scnt;i++)
            {
                if(dis[i]>ans)
                    ans=dis[i];
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    /*
    100
    2 2
    **
    *9
    0 1
    0 1
    0 0
    */
    


     

  • 相关阅读:
    Linux iptables常用命令
    Docker数据卷
    Ubuntu14.04下安装docker 1.9
    初识微服务
    初识微服务
    无状态服务(stateless service)
    git生成ssh key 避免每次push都要输入账号密码
    fiddler和xampp安装成功后,网站打不开的原因
    ajax设置自定义请求头信息
    ajax跨域之设置Access-Control-Allow-Origin
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134118.html
Copyright © 2020-2023  润新知