usaco 3.3 Camelot

终于过了这道题。。。但是这肯定不是正解,并没有办法证明它的正确性,但也足以过掉绝大多数数据了。

/*
ID: huanrui ke
PROG: camelot
LANG: C++
*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1200;
const int INF=1e9+10;

struct Point
{
    int x,y;
};Point p[maxn];
int n,m;
int fid[maxn][maxn],idn;
int dt[maxn],dk[maxn];
int dra[maxn],drn;
int king;
int dx[]={0,0,0,-1,1,-1,-1,1,1};
int dy[]={0,-1,1,0,0,-1,1,-1,1};
int dc[]={0,1,1,1,1,1,1,1,1};
int dx1[]={-1,-1,-2,-2,1,1,2,2};
int dy1[]={-2,2,-1,1,-2,2,-1,1};

void init()
{
    cin>>m>>n;
    MS0(fid);idn=0;
    REP(i,1,n){
        REP(j,1,m){
            fid[i][j]=++idn;
            p[idn]={i,j};
        }
    }
}

void read()
{
    char xc;int x,y;
    cin>>xc>>y;x=xc-'A'+1;
    king=fid[x][y];
    drn=0;
    while(cin>>xc>>y){
        x=xc-'A'+1;
        dra[++drn]=fid[x][y];
    }
}

bool vis[maxn];
struct Node
{
    int x,y;
    int d;
};

void bfs(int s,int *dt)
{
    REP(i,1,idn) dt[i]=INF;
    MS0(vis);
    queue<Node> q;
    q.push({p[s].x,p[s].y,0});
    dt[s]=0;
    vis[s]=1;
    while(!q.empty()){
        Node u=q.front();q.pop();
        REP(i,0,7){
            int nx=u.x+dx1[i],ny=u.y+dy1[i];
            if(nx<1||nx>n||ny<1||ny>m) continue;
            int nid=fid[nx][ny];
            if(vis[nid]) continue;
            vis[nid]=1;
            dt[nid]=u.d+1;
            q.push({nx,ny,u.d+1});
        }
    }
}

void solve()
{
    int ans=INF;
    REP(s,1,idn){
        int tmp=0;
        bfs(s,dt);
        bool flag=1;
        REP(k,1,drn){
            if(dt[dra[k]]==INF){
                flag=0;break;
            }
            tmp+=dt[dra[k]];
        }
        if(!flag) continue;
        REP(cc,1,2){
            REP(c,0,8){
                int nx=p[king].x+dx[c]*cc,ny=p[king].y+dy[c]*cc;
                if(nx<1||nx>n||ny<1||ny>m) continue;
                int j=fid[nx][ny];
                bfs(j,dk);
                REP(k,1,drn){
                    int i=dra[k];
                    if(dt[i]==INF) continue;
                    int tmp2=tmp-dt[i];
                    int t3=dt[j]+dc[c]*cc+dk[i];
                    ans=min(ans,tmp2+t3);
                }
            }
        }
    }
    if(drn==0) ans=0;
    cout<<ans<<endl;
}

int main()
{
    #define ONLINE_JUDGE
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #else
        freopen("camelot.in","r",stdin);
        freopen("camelot.out","w",stdout);
    #endif
    init();
    read();
    solve();
    return 0;
}
View Code

 

posted @ 2016-02-14 11:49  __560  阅读(206)  评论(0编辑  收藏  举报