poj3411——Paid Roads

来源:互联网 发布:sql设置主键语句 编辑:程序博客网 时间:2024/06/07 11:56

题目大意:给出N个城市m条路(有向路),两个城市之间可能连有多条路,经过一条从城市ai到bi的路i的付费方式有两种,如果之前到过城市ci则付费Pi,否则就在到达bi时付费Ri,问从城市1到城市N的最小代价

输入:N m

           第i条路的描述(共m行, ai, bi, ci, Pi, Ri (1 ≤ m, N ≤ 10, 0 ≤ Pi , Ri ≤ 100, Pi ≤ Ri))

输出:最小代价(如果没有从1到N的路线则输出impossible)

分析:dfs+“闸数”技巧

           最优路径中可能会存在环,也就是说可能会访问某个节点多次。因为N<=10,所以任意一个点最多存在于四个环里,也就是最多访问4次,这个次数被称为闸数(这个数到底是几有待考察,好多结题报告都不一样,而且没有解释理由)。将bool vis[]这个标记数组改为int vis[]即可。

代码:转载自http://blog.csdn.net/lyy289065406/article/details/6689310

  1. #include<iostream>  
  2. using namespace std;  
  3.   
  4. int n;  //城市数  
  5. int m;  //道路数  
  6. int vist[11];  //记录城市的访问次数,每个城市最多经过3次  
  7. int MinCost;  //最小总花费  
  8. struct  
  9. {  
  10.     int a,b,c,p,r;  
  11. }road[11];  //每条道路的付费规则  
  12.   
  13. void DFS(int a,int fee)   //a:当前所在城市,fee:当前方案的费用  
  14. {  
  15.     if(a==n && MinCost>fee)  
  16.     {  
  17.         MinCost=fee;  
  18.         return;  
  19.     }  
  20.   
  21.     for(int i=1;i<=m;i++)  //枚举道路  
  22.     {  
  23.         if(a==road[i].a && vist[ road[i].b ]<=3)  
  24.         {  
  25.             int b=road[i].b;  
  26.             vist[b]++;  
  27.   
  28.             if(vist[ road[i].c ])  
  29.                 DFS(b,fee+road[i].p);  
  30.             else  
  31.                 DFS(b,fee+road[i].r);  
  32.   
  33.             vist[b]--;       //回溯  
  34.         }  
  35.     }  
  36.     return;  
  37. }  
  38.   
  39. int main(void)  
  40. {  
  41.     while(cin>>n>>m)  
  42.     {  
  43.         memset(vist,0,sizeof(vist));  
  44.         vist[1]=1;    //从城市1出发,因此预记录到达1次  
  45.         MinCost=2000;  
  46.   
  47.         for(int i=1;i<=m;i++)  
  48.             cin>>road[i].a>>road[i].b>>road[i].c>>road[i].p>>road[i].r;  
  49.   
  50.         DFS(1,0);  
  51.         if(MinCost==2000)  
  52.             cout<<"impossible"<<endl;  
  53.         else  
  54.             cout<<MinCost<<endl;  
  55.     }  
  56.     return 0;  
  57. }

原创粉丝点击