• hdu4076Haunted Graveyard


    View Code
    /*hdu4076Haunted Graveyard
    题意:一块h*w的墓地,每个格子可能是石头(障碍),洞(在t秒后到达某个位置,t可能为负),草地
    (,0)为入口,(h-1,w-1)为出口。问从入口到出口的最短用时,若到不了输出Impossible,若用时无限小输出Never
    无限小:存在负权回路
    思路:存在负权,显然要用spfa。当对某一个点的松弛次数超过该图的顶点数h*w时就表示存在负权回路。
    但是有一点需要注意:判断负权回路的时候不能把终点算在内,因为当第一次走到终点的时候就走出去了,终点不会对他的后继点进行松弛。
    */
    #include<iostream>
    #include<queue>
    #include<algorithm>
    using namespace std;
    #define MAXN 35
    #define INF 100000000
    typedef pair<int,int> pii;
    int isStone[MAXN][MAXN],isHole[MAXN][MAXN],d[MAXN][MAXN],vis[MAXN][MAXN];//vis[]//[]记录松弛次数,d[][]表示耗时
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    int h,w,flag;//flag==1不存在最小路径(无限小)
    struct HOLE
    {
    int x2,y2,t;
    }hole[MAXN*MAXN];
    bool out(int x,int y)
    {
    if(x<0||x>=h||y<0||y>=w)return true;
    return false;
    }
    void BF()
    {
    queue <pii> q;
    bool inq[MAXN][MAXN];
    for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
    d[i][j]=INF;
    d[0][0]=0;
    memset(inq,0,sizeof(inq));
    memset(vis,0,sizeof(vis));
    inq[0][0]=1;
    vis[0][0]=1;
    q.push(make_pair(0,0));
    while(!q.empty())
    {
    pii tmp;
    tmp=q.front(),q.pop();
    inq[tmp.first][tmp.second]=0;
    if(tmp.first==h-1&&tmp.second==w-1)continue;
    if(vis[tmp.first][tmp.second]>h*w){flag=1;return;}
    if(isHole[tmp.first][tmp.second])//如果当前所在点是洞,不能停留
    {
    int index=isHole[tmp.first][tmp.second];
    int xx=hole[index].x2,yy=hole[index].y2;
    if(d[xx][yy]>d[tmp.first][tmp.second]+hole[index].t)
    {

    d[xx][yy]=d[tmp.first][tmp.second]+hole[index].t;vis[xx][yy]++;//松弛次数+1
    if(!inq[xx][yy]){q.push(make_pair(xx,yy)),inq[xx][yy]=1;}
    }
    continue;
    }
    for(int i=0;i<4;i++)
    {
    int x=tmp.first+dir[i][0];
    int y=tmp.second+dir[i][1];
    if(out(x,y))continue;
    if(isStone[x][y])continue;
    if(d[x][y]>d[tmp.first][tmp.second]+1)
    {
    d[x][y]=d[tmp.first][tmp.second]+1;vis[x][y]++;//松弛次数+1
    if(!inq[x][y]){q.push(make_pair(x,y)),inq[x][y]=1;}
    }
    }
    }
    }
    int main()
    {
    int stoneNum,holeNum,x1,y1;
    while(scanf("%d%d",&h,&w)==2)
    {
    if(!w&&!h)break;
    scanf("%d",&stoneNum);
    memset(isStone,0,sizeof(isStone));
    memset(isHole,0,sizeof(isHole));
    for(int i=0;i<stoneNum;i++)
    {
    scanf("%d%d",&x1,&y1);
    isStone[x1][y1]=1;
    }
    scanf("%d",&holeNum);
    for(int i=1;i<=holeNum;i++)
    {
    scanf("%d%d%d%d%d",&x1,&y1,&hole[i].x2,&hole[i].y2,&hole[i].t);
    isHole[x1][y1]=i;
    }
    flag=0;
    BF();
    if(flag)printf("Never\n");
    else if(d[h-1][w-1]==INF)printf("Impossible\n");
    else printf("%d\n",d[h-1][w-1]);
    }
    }

  • 相关阅读:
    O(n^2)的排序方法
    99乘法表
    excel 转 csv
    批量关闭 excel
    tomcat 加入服务
    文件打包 zip
    字符串转换
    List数组种删除数据
    mybatis 批量上传
    sql server 查询表字段及类型
  • 原文地址:https://www.cnblogs.com/sook/p/2226442.html
Copyright © 2020-2023  润新知