POJ3411 Paid Roads DFS

题目大意:有n个城市和m条道路(城市编号为1到n),从a城市经过c城市到达b城市(这里的a和c可以是同一个城市)的过路费有两种:(1)如果c城市已经走过,那么路费为p;(2)c城市没有走到过时路费为r;现在给出m条道路的信息,让你求出从城市1到城市n所需的最少路费。

分析:乍一看这倒题像是图论中的最短路问题,可是仔细想想并不是那回事。题中并没有说哪两个城市之间可达,只是说了从a城市经过c城市到达b城市的两种过路方法,这就意味着,只要有费用,那么这m条道路都可以走一遍。并且每一个城市还可以不止走一次。至于可以重复走多少次,则与m的值有关了,题中m是小于等于10的,这就说明每个城市最多是可以走10次的,但这样显然TLE。不断缩小可知重复走的次数,最后发现每个成熟最多可以走两次(至于为什么,,,这个我现在还不明白,,真抱歉=_=!)

实现代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int n,m,mincost;
int s[11];
typedef struct node
{
    int a,b,c,p,r;
}edge;
edge road[11];
void dfs(int ans,int fee)//a纪录当前所在的城市,fee纪录此方案当前的费用
{
    if(ans==n&&mincost>fee)
    {
        mincost=fee;
        return ;
    }
    for(int i=1;i<=m;i++)
      if(ans==road[i].a&&s[road[i].b]<=2)
      {
          s[road[i].b]++;
          if(s[road[i].c])  dfs(road[i].b,fee+road[i].p);
          else dfs(road[i].b,fee+road[i].r);
          s[road[i].b]--;
      }
    return ;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=-1)
    {
        memset(s,0,sizeof(s));
        s[1]=1;
        mincost=2000;
        for(int i=1;i<=m;i++)
          scanf("%d%d%d%d%d",&road[i].a,&road[i].b,&road[i].c,&road[i].p,&road[i].r);
        dfs(1,0);
        if(mincost==2000) puts("impossible");
        else printf("%d\n",mincost);
    }
    return 0;
}


你可能感兴趣的:(POJ3411 Paid Roads DFS)