您的位置:首页 > 其它

POJ 3311 Hie with the Pie 担货郎问题 DP Floyd/Dijkstra + DFS

2015-08-12 23:55 246 查看

POJ 3311 Hie with the Pie

题目描述:

  题目链接:POJ 3311 Hie with the Pie

题目大意:

  主人公要给nn个地点送披萨。由于交通问题在任意两个地点之间往返用时不同。现在从披萨店出发要给所有的点都送一份披萨,最后好回到披萨店。问最短用时。

  

解题思路:

  这是一个担货郎问题。即要给所有的地方都送或并且最后要回到起点。则可用FloydFloyd来求出,任意两点之间最短路。然后通过dfsdfs遍历求出全程的最短路即可。除了使用FloydFloyd之外,还可调用nn次DijkstraDijkstra来求出任意两点之间的最短路。复杂程度两者相同,不过,FloydFloyd更节省代码。

  

复杂度分析:

时间复杂度 :O(n3)O(n^3)

空间复杂度 :O(n2)O(n^2)

AC代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
const int INF = 0x3fffffff;
const int maxn = 15;
int via[maxn][maxn];
bool vis[maxn];
int ans;

struct Heapnode{
int d,u;
bool operator < (const Heapnode& rhs) const{
return d > rhs.d;
}
};

struct Edge{
int form,to,dist;
};

struct Dijkstra{
int n,m;
vector<Edge> edges;
vector<int> G[maxn];
bool done[maxn];
int d[maxn];
int p[maxn];

void init(int n){
this->n = n;
for(int i = 0; i < n; i++) G[i].clear();
edges.clear();
}

void AddEdge(int from, int to,int dist){
edges.push_back((Edge){from,to,dist});
m = edges.size();
G[from].push_back(m-1);
}

void dijkstra(int s){
priority_queue<Heapnode>Q;
for(int i = 0; i < n; i++)d[i] = INF;
d[s] = 0;
memset(done,0,sizeof(done));
Q.push((Heapnode){0,s});
while(!Q.empty()){
Heapnode x = Q.top();
Q.pop();
int u = x.u;
if(done[u]) continue;
done[u] = true;
for(int i = 0; i < G[u].size(); i++) {
Edge&e = edges[G[u][i]];
if(d[e.to] > d[u] + e.dist){
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push((Heapnode){d[e.to],e.to});
}
}
}
}
};

void dfs(int time,int cnt,int sit,int n){
// cout << sit <<endl;
if(cnt == n){
//cout << "**" << endl;
int tmp = ans;
if(ans > via[sit][0] + time){
ans = via[sit][0] + time;
//cout << sit << " " << ans << " " << tmp << endl;
}
return;
}
for(int i = 0; i < n+1; i++){
if(vis[i])continue;
vis[i] = true;
dfs(time+via[sit][i],cnt+1,i,n);
vis[i] = false;
}
}

int main(){
int n;
while(scanf("%d",&n)&&n){
int t;
Dijkstra a;
a.init(n+1);
for(int i = 0; i < n+1; i++)
for(int j = 0; j < n+1; j++){
scanf("%d",&t);
a.AddEdge(i,j,t);
}
memset(via,0,sizeof(via));
memset(vis,false,sizeof(vis));
for(int i = 0; i < n+1; i++){
a.dijkstra(i);
for(int j = 0; j < n+1; j++)
via[i][j] = a.d[j];
}
// for(int i = 0; i < n+1; i++){
// for(int j = 0; j < n+1; j++){
//     printf("%d",via[i][j]);
// }
printf("\n");}
ans = INF;
vis[0] = true;
dfs(0,0,0,n);
printf("%d++\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: