zoukankan      html  css  js  c++  java
  • UVA 1078 Steam Roller 建图 Dijksta

    把一个点(r,c)拆成(r,c,dir,doubled)八个点

    表示上个点是从dir方向到(r,c)的,doubled表示那条边是否已经加倍。

    而后就是考虑清楚细节,建图。

    最后跑最短路。

    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<cmath>
    #include<climits>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    #define pb(a) push(a)
    #define INF 0x1f1f1f1f
    #define lson idx<<1,l,mid
    #define rson idx<<1|1,mid+1,r
    #define PI  3.1415926535898
    template<class T> T min(const T& a,const T& b,const T& c) {
        return min(min(a,b),min(a,c));
    }
    template<class T> T max(const T& a,const T& b,const T& c) {
        return max(max(a,b),max(a,c));
    }
    void debug() {
    #ifdef ONLINE_JUDGE
    #else
    
        freopen("d:\in1.txt","r",stdin);
        freopen("d:\out1.txt","w",stdout);
    #endif
    }
    int getch() {
        int ch;
        while((ch=getchar())!=EOF) {
            if(ch!=' '&&ch!='
    ')return ch;
        }
        return EOF;
    }
    struct HeapNode
    {
        int d,u;
        bool operator < (const HeapNode &ant) const
        {
            return d>ant.d;
        }
    };
    struct Edge
    {
        int from,to;
        int dist;
    };
    const int maxc=105;
    const int maxr=105;
    const int maxn=8*maxr*maxc;
    struct Dijksta
    {
        int n;
        vector<int> g[maxn];
        vector<Edge> edge;
        int d[maxn];
        int done[maxn];
        void init(int n)
        {
            this->n = n;
            for(int i=0;i<n;i++)
                g[i].clear();
            edge.clear();
        }
        void add(int u,int v,int w)
        {
            Edge e=(Edge){u,v,w};
            edge.push_back(e);
            g[u].push_back(edge.size()-1);
        }
        void solve(int s)
        {
            memset(d,INF,sizeof(d));
            memset(done,0,sizeof(done));
            d[s]=0;
            priority_queue<HeapNode> q;
            q.push((HeapNode){0,s});
    
            while(!q.empty())
            {
                HeapNode x=q.top();q.pop();
                if(done[x.u])continue;
                int u=x.u;
                done[u]=1;
                for(int i=0;i<g[u].size();i++)
                {
                    Edge &e=edge[g[u][i]];
                    if(e.dist+d[u]<d[e.to])
                    {
                        d[e.to]=d[u]+e.dist;
                        q.push((HeapNode){d[e.to],e.to});
                    }
                }
            }
        }
        int findD(int e)
        {
            return d[e];
        }
    };
    int R,C,r1,r2,c1,c2;
    int n;
    int grid[maxr][maxc][4];
    const int UP=0,RIGHT=1,DOWN=2,LEFT=3;
    int inv[]={2,3,0,1};
    int dr[]={-1,0,1,0};
    int dc[]={0,1,0,-1};
    Dijksta solver;
    
    int id[maxr][maxc][4][2];
    int ID(int r,int c,int dir,int doubled)
    {
        int &x=id[r][c][dir][doubled];
        if(x>0)return x;
        else return x=++n;
    }
    
    int readint()
    {
        int x;scanf("%d",&x);return x;
    }
    void read()
    {
        for(int r=1;r<=R;r++)
        {
            for(int c=1;c<C;c++)
                grid[r][c][RIGHT]=grid[r][c+1][LEFT]=readint();
            if(r!=R)for(int c=1;c<=C;c++)
                grid[r][c][DOWN]=grid[r+1][c][UP]=readint();
        }
    }
    
    bool cango(int r,int c,int dir)
    {
        if(r<1||r>R||c<1||c>C)return false;
        return grid[r][c][dir]>0;
    }
    
    void construct()
    {
        for(int r=1;r<=R;r++)
            for(int c=1;c<=C;c++)
                for(int d=0;d<4;d++)if(cango(r,c,inv[d]))
                    for(int nd=0;nd<4;nd++)if(cango(r,c,nd))
                        for(int doubled=0;doubled<2;doubled++)
                        {
                            int nr=r+dr[nd];
                            int nc=c+dc[nd];
                            int v=grid[r][c][nd];
                            int ndoubled=0;
                            if(d!=nd)
                            {
                                if(!doubled)v+=grid[r][c][inv[d]];
                                ndoubled=1;v+=grid[r][c][nd];
                            }
                            solver.add(ID(r,c,d,doubled),ID(nr,nc,nd,ndoubled),v);
                        }
    }
    int main()
    {
        int ca=0;
        while(scanf("%d%d%d%d%d%d",&R,&C,&r1,&c1,&r2,&c2)!=EOF&&R)
        {
            read();
    
            n=0;
            memset(id,0,sizeof(id));
            solver.init(R*C*8+1);
    
            for(int d=0;d<4;d++)if(cango(r1,c1,d))
                solver.add(0,ID(r1+dr[d],c1+dc[d],d,1),grid[r1][c1][d]*2);
            construct();
    
            solver.solve(0);
    
            int ans=INF;
            for(int d=0;d<4;d++)if(cango(r2,c2,inv[d]))
                for(int doubled=0;doubled<2;doubled++)
                {
                    int v=solver.findD(ID(r2,c2,d,doubled));
                    if(!doubled)v+=grid[r2][c2][inv[d]];
                    ans=min(ans,v);
                }
            printf("Case %d: ",++ca);
            if(ans!=INF)printf("%d
    ",ans);
            else printf("Impossible
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ubuntu远程windows桌面
    spring boot 给返回值加状态 BaseData
    spring boot 拦截异常 统一处理
    IntelliJ IDEA spring boot 远程Ddbug调试
    IntelliJ IDEA 常用插件
    spring boot 请求地址带有.json 兼容处理
    spring boot 接口返回值去掉为null的字段
    spring boot 集成disconf
    Spring boot 自定义拦截器
    Linux下安装MySQL
  • 原文地址:https://www.cnblogs.com/BMan/p/3632956.html
Copyright © 2011-2022 走看看