题目大意是:给定一个N和M,N代表城市数目(城市以1-N命名),其中有M条边连接这些城市,城市之间可能有重边。接下来有M行。每行有5个输入,分别为ai,bi,ci,pi和ri。ai表示第i条边的起始城市,bi表示第i条边的末尾城市。经过每条边都需要付钱,有两种付钱方式,付钱数分别为pi和ri,当且仅当ci这个城市之前有经过,才可以用ri这种付钱方式。然后要求找出一条付钱数最少的从城市1到城市N的路径。
思路:DFS,题目中包含着一个隐含条件是每个城市可以走一遍以上,所以不能通过简单的布尔类型设置visit数组,而要记录访问过的次数,代码中设置访问次数<=3才继续访问。
#include <iostream>
using namespace std;
#include <stdio.h>
#include <memory.h>
#include <vector>
struct node {
int bi,ci,pi,ri;
};
vector<struct node> data[11];
int n,m;
int visit_time[14];
int answer;
void DFS(int s, int cost) {
int i,j;
struct node temp;
//必须加这句判断,否则会出错,同时起到剪枝的效果
if (cost>answer)
return;
if (s==n) {
answer=cost;
return;
}
for (i=0;i<data[s].size();i++) {
temp=data[s][i];
if (visit_time[temp.bi]<=3) {
visit_time[temp.bi]++;
if (visit_time[temp.ci]>0)
DFS(temp.bi,cost+temp.pi);
else
DFS(temp.bi,cost+temp.ri);
visit_time[temp.bi]--;
}
}
}
int main()
{
int i,j,k;
int tempa,tempb,tempc,tempp,tempr;
struct node temp;
scanf("%d%d",&n,&m);
memset(visit_time,0,sizeof(visit_time));
for (i=0;i<m;i++) {
scanf("%d%d%d%d%d",&tempa,&tempb,&tempc,&tempp,&tempr);
temp.bi=tempb;
temp.ci=tempc;
temp.pi=tempp;
temp.ri=tempr;
data[tempa].push_back(temp);
}
answer=999999999;
DFS(1,0);
if (answer==999999999)
printf("impossible\n");
else
printf("%d\n",answer);
return 0;
}