POJ3592-图论综合题tarjan+spfa

/*
觉得总是在没想明白之前看解题报告太猥琐了,这题不难但WA了无数遍,仔细看了别人的代码才改了过来,改来改去只改了一处,我还想不通为什么,这样的一个code过程郁闷得要死~
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int NN=1606;
const int MM=1000000;
const int INF=0x3fffffff;

int n,m,w[NN],val[NN];
char c[42][42];
vector<int> adj[NN];

struct Edge{
    int u,v,next;
}edge[MM];
int ecnt,head[NN];
void addedge(int u,int v)
{
    edge[ecnt].u=u;
    edge[ecnt].v=v;
    edge[ecnt].next=head[u];
    head[u]=ecnt++;
}

int bcnt,top,depth,stack[NN],dfn[NN],low[NN],belong[NN];
bool instack[NN];
void tarjan(int u)
{
    dfn[u]=low[u]=++depth;
    stack[++top]=u;
    instack[u]=true;
    int v;
    for (int i=head[u]; i!=-1; i=edge[i].next)
    {
        v=edge[i].v;
        if (!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if (instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if (low[u]==dfn[u])
    {
        adj[bcnt].clear();
        val[bcnt]=0;
        do
        {
            v=stack[top--];
            instack[v]=false;
            belong[v]=bcnt;
            val[bcnt]+=w[v];
        }while (v!=u);
        bcnt++;
    }
}

bool vis[NN]={0};
int dis[NN];
int lpfa(int S)
{
    for (int i=0; i<bcnt; i++) dis[i]=-INF;
    dis[S]=0;
    queue<int> q;
    q.push(S);
    while (!q.empty())
    {
        int u=q.front();
        vis[u]=false;
        q.pop();
        for (int i=0; i<adj[u].size(); i++)
        {
            int v=adj[u][i];
            if (dis[v]<dis[u]+val[v])
            {
                dis[v]=dis[u]+val[v];
                if (!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
    int ret=0;
    for (int i=0; i<bcnt; i++) if (dis[i]>ret) ret=dis[i];
    return ret+val[S];
}

int main()
{
    int cas;
    scanf("%d",&cas);
    while (cas--)
    {
        scanf("%d%d",&n,&m);
        for (int i=0; i<n; i++)
        {
            getchar();
            for (int j=0; j<m; j++) c[i][j]=getchar();
        }
        ecnt=0;
        for (int i=0; i<n*m; i++)
        {
            head[i]=-1;
            dfn[i]=0;
        }
        int x,y;
        for (int i=0; i<n; i++)
          for (int j=0; j<m; j++)
          {
              if (c[i][j]=='#') { w[i*m+j]=0; continue; } //加了w[i*m+j]=0;一句后才AC,不能理解‘#’处的点在这之后就用不上了,给w赋值怎么就有影响了?Wait one mimute... 如果‘*’处的点通过magic power 到达的点是'#'呢?考虑不周~~晕死~~
              if (c[i][j]=='*')
              {
                  w[i*m+j]=0;
                  scanf("%d%d",&x,&y);
                  addedge(i*m+j,x*m+y);
              }
              else w[i*m+j]=c[i][j]-'0';
              if (i!=n-1 && c[i+1][j]!='#') addedge(i*m+j,(i+1)*m+j);
              if (j!=m-1 && c[i][j+1]!='#') addedge(i*m+j,i*m+j+1);
          }
        bcnt=top=depth=0;
        for (int i=0; i<n*m; i++) if (!dfn[i]) tarjan(i);
        int u,v;
        for (int i=0; i<ecnt; i++)
        {
            u=edge[i].u; v=edge[i].v;
            if (belong[u]!=belong[v]) adj[belong[u]].push_back(belong[v]);
        }
        printf("%d\n",lpfa(belong[0]));//最长路就写lpfa,哈哈,幼稚~~
    }
    return 0;
}

你可能感兴趣的:(POJ3592-图论综合题tarjan+spfa)