[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; }