hdu 4076 Haunted Graveyard - spfa(負權迴路)

/*
hdu 4076 Haunted Graveyard - spfa(負權迴路)
題意:有n*m個點,每一點可以向四個方向走,有些點是墓地不能走,有些點是山洞,當你走到該點時會傳送到另外一點,所花費的時間有可能是個正數也可能是個負數
也可能是0。起點是(0,0),目的地是(n-1,m-1),題目保證起點和終點不會是墓地也不會是山洞。如果有可能永遠都到達不了終點也就是該圖存在負權迴路,輸出Never;
否則輸出需最少的花費時間或者Impossible;
思路:存在負權,顯然要用spfa。當對某一個點的鬆弛次數超時該圖的頂點數n*m時就表示存在負權迴路。
但是有一點需要注意:判斷負權迴路的時候不能把終點算在內,因爲當第一次走到終點的時候就走出去了,終點不會對他的後繼點進行鬆弛。
*/
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#define inf 0xfffffff
const int N=35;
int map[N][N],xx[N][N],yy[N][N],tt[N][N],dist[N][N],vis[N][N],cnt[N][N];
int dir[4][2]= { {0,1},{0,-1},{1,0},{-1,0} };
int W,H,flag;
struct node
{
    int x,y;
};
void spfa()
{
    int i,j,ans;
    for(i=0; i<W; ++i)
    {
        for(j=0; j<H; ++j)
        {
            dist[i][j]=inf;
        }
    }
    dist[0][0]=0;
    memset(vis,0,sizeof(vis));
    memset(cnt,0,sizeof(cnt));
    queue<node> q;
    node cur,next;
    cur.x=0;
    cur.y=0;
    next.x=next.y=0;
    q.push(cur);
    vis[0][0]=1;
    cnt[0][0]++;
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        vis[cur.x][cur.y]=0;//是否在隊列內
        if(cnt[cur.x][cur.y]>W*H)
        {
            flag=1;
            return;
        }
        if(cur.x==W-1&&cur.y==H-1)continue;
        if(xx[cur.x][cur.y]!=-1)
        {
            next.x=xx[cur.x][cur.y];
            next.y=yy[cur.x][cur.y];
            ans=dist[cur.x][cur.y]+tt[cur.x][cur.y];
            if(dist[next.x][next.y]>ans)
            {
                dist[next.x][next.y]=ans;
                if(vis[next.x][next.y]==0)
                {
                    vis[next.x][next.y]=1;
                    cnt[next.x][next.y]++;
                    q.push(next);
                }
            }
            continue;
        }

        for(i=0; i<4; ++i)
        {
            next.x=cur.x+dir[i][0];
            next.y=cur.y+dir[i][1];
            ans=dist[cur.x][cur.y]+1;
            if(next.x<0 || next.y<0 || next.x>=W || next.y>=H || map[next.x][next.y]==1) continue;
            if(dist[next.x][next.y]>ans)
            {
                dist[next.x][next.y]=ans;
                if(vis[next.x][next.y]==0)
                {
                    vis[next.x][next.y]=1;
                    cnt[next.x][next.y]++;
                    q.push(next);
                }
            }
        }
    }
}
int main()
{
    int numofmu,numofdong,i,tempa,tempb;
    while(cin>>W>>H,W+H)
    {
        flag=0;
        memset(map,0,sizeof(map));
        memset(xx,-1,sizeof(xx));
        cin>>numofmu;
        for(i=1; i<=numofmu; ++i)
        {
            cin>>tempa>>tempb;
            map[tempa][tempb]=1;
        }
        cin>>numofdong;
        for(i=1; i<=numofdong; ++i)
        {
            cin>>tempa>>tempb;
            cin>>xx[tempa][tempb]>>yy[tempa][tempb]>>tt[tempa][tempb];
        }
        spfa();
        if(flag==1) cout<<"Never"<<endl;
        else if(dist[W-1][H-1]==inf) cout<<"Impossible"<<endl;
        else cout<<dist[W-1][H-1]<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章