[ZOJ 3318] Strange Country [搜索]
2014-08-10 09:57
267 查看
有m个地图。你要在每个地图上找一条s到t的路。总的费用是每条路的长度的和,对于每两个相邻的地图,若你选的路不完全相同,则额外需要1的费用。问总的最小费用。
记录满足当前最小费用的所有的结果。最开始记录等于最短路长度的所有路。按照地图一层一层向下推即可。每次抛弃掉不是最短的那部分。
复杂度不太会算,不过感觉上最短路的条数不会超过根号n的根号n次方这么多条。所以也就三千条左右。复杂度应该是30*30*3000的吧..200组case...
记录满足当前最小费用的所有的结果。最开始记录等于最短路长度的所有路。按照地图一层一层向下推即可。每次抛弃掉不是最短的那部分。
复杂度不太会算,不过感觉上最短路的条数不会超过根号n的根号n次方这么多条。所以也就三千条左右。复杂度应该是30*30*3000的吧..200组case...
#include <cstdio> #include <vector> #include <queue> #include <cstring> #include <iostream> using namespace std; struct Path { vector<int> p; int v; friend bool operator == (const Path &a,const Path &b) { if (a.p!=b.p||a.v!=b.v) return false; return true; } }; int n,m,s,t,minv; queue<Path> ans; queue<Path> tmp; queue<Path> que; bool a[31][31]; void readmap() { memset(a,0,sizeof(a)); int r,x,y; scanf("%d",&r); while (r--) { scanf("%d%d",&x,&y); a[x][y]=a[y][x]=true; } } bool in(int x,vector<int> &c) { if (x==s) return true; for (int i=0;i<c.size();i++) if (x==c[i]) return true; return false; } void print(Path &p) { printf("%d",s); for (int i=0;i<p.p.size();i++) printf(" %d",p.p[i]); printf(": %d\n",p.v); } void printans() { Path x=ans.front(); do { print(ans.front()); ans.push(ans.front()); ans.pop(); } while (!(ans.front()==x)); } void cal1() { while (!que.empty()) que.pop(); while (!ans.empty()) ans.pop(); Path x; x.v=0; que.push(x); minv=100000; while (!que.empty()) { Path &x=que.front(); int i=s,j; if (x.p.size()!=0) i=x.p[x.p.size()-1]; if (i==t) { minv=min(minv,x.v); ans.push(x); } if (x.v>minv) return; for (j=1;j<=n;j++) { if (a[i][j]&&!in(j,x.p)) { Path y=x; y.v++; y.p.push_back(j); que.push(y); } } que.pop(); } } bool hasPath(vector<int> &p) { int last=s; for (int i=0;i<p.size();i++) { if (!a[last][p[i]]) return false; last=p[i]; } return true; } void cal2() { while (!que.empty()) que.pop(); while (!tmp.empty()) tmp.pop(); int lastminv=minv; Path x; x.v=0; que.push(x); minv=100000; while (!que.empty()) { Path &x=que.front(); int i=s,j; if (x.p.size()!=0) i=x.p[x.p.size()-1]; if (i==t) { x.v+=lastminv+1; minv=min(minv,x.v); tmp.push(x); } if (x.v>minv) break; for (j=1;j<=n;j++) { if (a[i][j]&&!in(j,x.p)) { Path y=x; y.v++; y.p.push_back(j); que.push(y); } } que.pop(); } while (!ans.empty()) { Path &x=ans.front(); if (hasPath(x.p)) { x.v+=x.p.size(); tmp.push(x); minv=min(minv,x.v); } ans.pop(); } while (!tmp.empty()) { Path &x=tmp.front(); if (x.v<=minv) { ans.push(x); } tmp.pop(); } } int main() { int tt; scanf("%d",&tt); while (tt--) { scanf("%d%d%d%d",&n,&m,&s,&t); m--; readmap(); cal1(); //printans(); while (m--) { readmap(); cal2(); //printans(); } printf("%d\n",minv); } return 0; }
相关文章推荐
- ZOJ 3805 Machine(搜索+技巧)【树形DP模板】
- 【ZOJ】2580【搜索】【suduku】
- ZOJ 1033 Ambiguous Dates (简单搜索)
- [ZOJ 3353] Chess Board [搜索+状态压缩]
- zoj 1101 搜索
- [搜索] ZOJ1002、ZOJ1008、ZOJ1019、POJ1011
- ZOJ 2562 数论+搜索
- ZOJ 3644 记忆化搜索
- ZOJ3376 Safest Points [几何(geometry), 宽度优先搜索(bfs)]
- 【搜索入门专题1】E - Farm Irrigation 【BFS】ZOJ 2412
- ZOJ 2849【瞎暴力的搜索】
- ZOJ 1649 Rescue BFS (搜索)
- ACM-ZOJ 2412 DFS 深度优先搜索
- 浙江大学2015年校赛F题 ZOJ 3865 Superbot BFS 搜索
- (01背包搜索) zoj 3013
- [ACM_搜索] ZOJ 1103 || POJ 2415 Hike on a Graph (带条件移动3盘子到同一位置的最少步数 广搜)
- zoj 1091 BFS简单搜索
- 图的搜索+回溯-Seeding(zoj 2100 )
- 广度优先搜索,分支限界- ZOJ - 1136 Multiple
- ZOJ 2008 Gnome Tetravex 搜索(DFS)