首页 > 代码库 > poj 3411 Paid Roads(dfs,可重复访问节点)
poj 3411 Paid Roads(dfs,可重复访问节点)
http://poj.org/problem?id=3411
大致题意:n个城市由m条公路连接,两个城市之间可能有多条公路连接。经过每条公路都需要收费,对于城市a,b,若之前经过城市c那么只需交p元钱,否则交r元钱。问从城市1到n的最小花费。
思路:由于经过每条公路的收费有两种方式,那么有的城市可能要经过多次,以便获得更小的花费,但也有可能出现有环的情况,那么该城市经过多次只会徒增花费。所以我们定义vis[]数组标记该城市访问的次数,在该题中(m <= 10)当一个城市访问超过3次(网上说这个与图的边数m有关)就可判定它在环中,没必要继续搜了。
#include <stdio.h> #include <iostream> #include <algorithm> #include <set> #include <map> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #define LL long long #define _LL __int64 #define eps 1e-8 using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 110; struct node { int v,c,p,r; }; vector <node> edge[20]; int n,m; int vis[20]; int ans; void dfs(int u, int cost) { if(cost >= ans) return; if(u == n) { if(ans > cost) ans = cost; return; } for(int i = 0; i < (int)edge[u].size(); i++) { int v = edge[u][i].v; if ( vis[v] <= 3 ) //搜索的限制条件,避免一个点走过超过3次出现环路。之前没加RE了。 { vis[v]++; if ( vis[edge[u][i].c]) dfs(v, cost + edge[u][i].p); else dfs(v, cost + edge[u][i].r); vis[v]--; } } } int main() { int a,b,c,p,r; while(~scanf("%d %d",&n,&m)) { for(int i = 0; i <= n; i++) edge[i].clear(); for(int i = 0; i < m; i++) { scanf("%d %d %d %d %d",&a,&b,&c,&p,&r); edge[a].push_back((struct node){b,c,p,r}); } memset(vis,0,sizeof(vis)); ans = INF; vis[1] = 1; dfs(1,0); if(ans == INF) printf("impossible\n"); else printf("%d\n",ans); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。