您的位置:首页 > 其它

[ZOJ 3318] Strange Country [搜索]

2014-08-10 09:57 267 查看
有m个地图。你要在每个地图上找一条s到t的路。总的费用是每条路的长度的和,对于每两个相邻的地图,若你选的路不完全相同,则额外需要1的费用。问总的最小费用。

记录满足当前最小费用的所有的结果。最开始记录等于最短路长度的所有路。按照地图一层一层向下推即可。每次抛弃掉不是最短的那部分。

复杂度不太会算,不过感觉上最短路的条数不会超过根号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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: