poj 3411 Paid Roads(dfs,可重复访问节点)

来源:互联网 发布:淘宝有流量没有转化率 编辑:程序博客网 时间:2024/05/23 23:38

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-8using 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);            elsedfs(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;}


0 0