poj 3592 缩点+SPFA

来源:互联网 发布:ssd固态硬盘优化软件 编辑:程序博客网 时间:2024/06/11 13:24

题意:给出一个矩阵,其中#代表墙,不可走,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 10000000int 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,'\0',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\n",ans);    }    return 0;}/*1002 2***90 10 10 0*/


 

原创粉丝点击