[BZOJ]1001 BJOI2006 狼抓兔子

新年做一道1001

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
using namespace std;

const int INF=0x7fffffff;
int n,m,n1,m2,z;
vector<vector<pair<int,int> > > edge;
vector<int> ans; // 到达时间
multiset<pair<int,int> > q; // 到达时间,编号 
 
inline void readEdge(int x, int y) {
    int v; cin>>v;
    edge[x].push_back(make_pair(y,v));
    edge[y].push_back(make_pair(x,v));
}

int main() {
    ios_base::sync_with_stdio(false);
    cin>>n>>m;
    n1=n-1;        // 图块行数 
    m2=(m-1)*2;    // 图块列数 
    z=n1*m2+1;    // 最后图块号 
    vector<pair<int, int> > t;
    for (int i=0;i<=z;i++) {
        edge.push_back(t);
        ans.push_back(INF);
    }
    
    if (n>1) {
        for (int j=1;j<m;j++) readEdge(z,2*j);     // 横线 第1排 
        for (int i=1;i<z-m2;i+=2) readEdge(i,i+m2+1); // 横线 ...
        for (int i=z-m2;i<z;i+=2) readEdge(0,i); // 横线 第n排 
    }
    else for (int j=1;j<m;j++) readEdge(z,0);    // 只有一条横线 
    
    if (m>1) for (int i=1;i<z;i+=m2) { // 竖线 
        readEdge(0,i);
        for (int j=i+2;j<i+m2;j+=2) readEdge(j-1,j);
        readEdge(z,i+m2-1);
    }
    else for(int i=0;i<n; i++)readEdge(z,0); // 只有一条竖线
    for (int i=1;i<z;i+=2) readEdge(i,i+1); // 斜线 

    q.insert(make_pair(0,0));
    while(!q.empty()) {
        int u=q.begin()->first, v=q.begin()->second;
        if (u<=ans[v]) {
            ans[v]=u;
            if (v==z) break;
            for (int i=0; i<edge[v].size(); i++) {
                int j=edge[v][i].first, w=u+edge[v][i].second;
                if (w<ans[j]) {
                    ans[j]=w;
                    q.insert(make_pair(w,j));
                }
            }
        }
        q.erase(q.begin());
    }
    cout<<ans[z]<<endl;
    return 0;
}

 

posted @ 2016-01-01 13:05  海豚爸爸  阅读(178)  评论(0编辑  收藏  举报