poj 3592 Instantaneous Transference

来源:互联网 发布:手机剪辑mp3软件 编辑:程序博客网 时间:2024/04/30 05:40

http://poj.org/problem?id=3592

这道题先有tarjan算法缩点,然后再建图,再有spfa算法求最长路。

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define maxn 300000using namespace std;const int inf=-1<<30;int e,head[maxn],belong[maxn],stack1[maxn],top,dfn[maxn],low[maxn],bcc_clock,bcnt,n,m,num1[100][100],num,gg[maxn],point[maxn],cc[maxn],ee,head1[maxn],dis[maxn],cnt[maxn],temp;bool vis[maxn],visi[maxn];int dir[2][2]= {{0,1},{1,0}};struct node{    int u,v,next;} p[maxn];struct node1{    int u,v,w,next;} pp[maxn];char g[50][50];void add(int u,int v){    p[e].u=u;    p[e].v=v;    p[e].next=head[u];    head[u]=e++;}void addnode(int u,int v,int w){    pp[ee].v=v;    pp[ee].u=u;    pp[ee].w=w;    pp[ee].next=head1[u];    head1[u]=ee++;}void tarjan(int u){    vis[u]=true;    dfn[u]=low[u]=++bcc_clock;    stack1[++top]=u;    for(int i=head[u]; i!=-1; i=p[i].next)    {        int v=p[i].v;        if(!dfn[v])        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(vis[v])            low[u]=min(low[u],dfn[v]);    }    if(dfn[u]==low[u])    {        bcnt++;        int j;        do        {            j=stack1[top--];            vis[j]=false;            belong[j]=bcnt;        }        while(j!=u);    }}void init(){    memset(dfn,0,sizeof(dfn));    memset(low,0,sizeof(low));    memset(belong,0,sizeof(belong));    memset(cc,0,sizeof(cc));    memset(vis,false,sizeof(vis));}void del(){    init();    for(int i=0; i<n*m; i++)    {        if(!dfn[i])        {            tarjan(i);        }    }}bool ralex(int u,int v,int c){    if(dis[v]<dis[u]+c)    {        dis[v]=dis[u]+c;        return true;    }    return false;}bool spfa(int src){    memset(visi,false,sizeof(visi));    memset(cnt,0,sizeof(cnt));    visi[src]=true;    for(int i=0; i<=bcnt; i++)    {        dis[i]=inf;    }    queue<int>q;    q.push(src);    dis[src]=0;    while(!q.empty())    {        int u=q.front();        q.pop();        visi[u]=false;        for(int i=head1[u]; i!=-1; i=pp[i].next)        {            if(ralex(u,pp[i].v,pp[i].w)&&!visi[pp[i].v])            {                if((++cnt[pp[i].v])>n*m) return false;                q.push(pp[i].v);                visi[pp[i].v]=true;            }        }    }    temp=0;    for(int i=1; i<bcnt+1; i++)    {        temp=max(temp,dis[i]);    }    return true;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        num=0;        int cn=0;        memset(head1,-1,sizeof(head1));        memset(head,-1,sizeof(head));        e=0,top=0,bcnt=0,bcc_clock=0,ee=0;        getchar();        for(int i=0; i<n; i++)        {            scanf("%s",g[i]);        }        for(int i=0; i<n; i++)        {            for(int j=0; j<m; j++)            {                int k=i*m+j;                if(g[i][j]=='#')                {                    gg[k]=-1;                    continue;                }                else                {                    if(g[i][j]=='*')                    {                        point[cn++]=k;                        gg[k]=0;                    }                    else if(g[i][j]>='0'&&g[i][j]<='9')                    {                        gg[k]=g[i][j]-'0';                    }                    for(int c=0; c<2; c++)                    {                        int xx=i+dir[c][0];                        int yy=j+dir[c][1];                        if(xx<n&&yy<m)                        {                            if(g[xx][yy]!='#')                            {                                add(k,xx*m+yy);                            }                        }                    }                }            }        }        for(int i=0; i<cn; i++)        {            int x,y;            scanf("%d%d",&x,&y);            if(g[x][y]!='#')            {                add(point[i],x*m+y);            }        }        del();        for(int i=0; i<n*m; i++)        {            cc[belong[i]]+=gg[i];        }        addnode(0,belong[0],cc[belong[0]]);        for(int i=0; i<n*m; i++)        {            for(int j=head[i]; j!=-1; j=p[j].next)            {                int v=p[j].v;                if(belong[i]!=belong[v])                {                    addnode(belong[i],belong[v],cc[belong[v]]);                }            }        }        spfa(0);        printf("%d\n",temp);    }    return 0;}


0 0
原创粉丝点击