牛客网-2018年湘潭大学程序设计竞赛-F

题目链接:https://www.nowcoder.com/acm/contest/105/F

解题思路:这道题第一眼直接思路就是搜索,但想了半天没想到有什么好办法搜,然后就转成最短路写了,

因为多入口和出口,建立一个汇点一个源点,权值自己设,然后上下左右能相连的权值为1,传送阵(能用的前提下)入口和出口两个点的权值设为3;

然后就是最短路;

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#define maxn 400005
#define inf 0x3f3f3f3f
using namespace std;
struct Edge
{
    int next;
    int to;
    int w;
}edge[maxn];
struct node
{
    int num;
    int dist;
    node(int _num=0,int _dist=0):num(_num),dist(_dist){}
    friend bool operator<(node a,node b)
    {
        return a.dist>b.dist;
    }
};
int head[maxn];
int cnt;
int dist[maxn];
int visit[maxn];
int ans[maxn];
void add(int u,int v,int w)
{
    edge[cnt].next=head[u];
    edge[cnt].to=v;
    edge[cnt].w=w;
    head[u]=cnt++;
}
void dij(int u)
{
    priority_queue<node>q;
    memset(dist,inf,sizeof(dist));
    memset(visit,0,sizeof(visit));
    dist[u]=0;
    q.push(node(u,0));
    while(!q.empty())
    {
        node p=q.top();
        q.pop();
        int now=p.num;
        for(int i=head[now];i!=-1;i=edge[i].next)
        {
            Edge e=edge[i];
            if(dist[e.to]>dist[now]+e.w)
            {
                dist[e.to]=dist[now]+e.w;
                q.push(node(e.to,dist[e.to]));
            }
        }
    }
}
int main()
{
    int n,m,q;
    int x,y,w;
    int tx,ty,ex,ey;
    int cot=0;
    char s[500][500];
    while(cin>>n>>m>>q)
    {
        cot=cnt=0;
        memset(head,-1,sizeof(head));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>s[i][j];
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
        {
            if(s[i][j]!='#')
            {
                if(s[i+1][j]!='#'&&i+1<=n)
                {
                    x=(i-1)*m+j;y=(i)*m+j;add(x,y,1);
                }
                if(s[i-1][j]!='#'&&i-1>=1)
                {
                    x=(i-1)*m+j;y=(i-2)*m+j;add(x,y,1);
                }
                if(s[i][j+1]!='#'&&(j+1)<=m)
                {
                    x=(i-1)*m+j;y=(i-1)*m+j+1;add(x,y,1);
                }
                if(s[i][j-1]!='#'&&(j-1)>=1)
                {
                    x=(i-1)*m+j;y=(i-1)*m+j-1;add(x,y,1);
                }
            }
            if(s[i][j]=='S')
            {
                x=0;y=(i-1)*m+j;add(x,y,1);
            }
            if(s[i][j]=='T')
            {
                ans[++cot]=(i-1)*m+j;
            }
        }
        while(q--)
        {
            cin>>tx>>ty>>ex>>ey;
            tx++;ty++;ex++;ey++;
            if(s[tx][ty]!='#'&&s[ex][ey]!='#')
            {
            x=(tx-1)*m+ty;y=(ex-1)*m+ey;
            add(x,y,3);
            }
        }
        dij(0);
        int a=inf;
        for(int i=1;i<=cot;i++)
        {
            a=min(a,dist[ans[i]]);
        }
        if(a==inf)
        cout<<"-1\n";
        else
        cout<<a-1<<endl;
    }
}

  

posted @ 2018-05-03 20:09  荒岛的龟  阅读(203)  评论(0编辑  收藏  举报