收费公路
【问题描述】
N 个城市有 m 条单向的公路连接, 两个城市之间可能存在多条路。 ai 表示第 i 条路的起
始城市,bi 表示第 i 条路的终点城市。经过每条边都需要付钱,有两种付钱方式,付钱数分
别为 Pi 和 Ri,当经过ci 这个城市后,才可以用 这种Pi付钱方式,否则需要支
付Ri。要求找出一条付钱数最少的从城市 1 到城市 N 的路径。
【输入】
第一行包括两个正整数 N 和 m,分别表示城市的数量和路的数量。接下来有 m 行,分
别表示 ai, bi, ci, Pi, Ri (1 ≤ i ≤ m)。用空格隔开,所有的输入均为整数。
【输出】
输出一行表示从城市 1 到 N 的最小花费,如果无法得到结果,则输出‘impossible’。
【输入输出样例】
road. . in road. . out
4 5
1 2 1 10 10
2 3 1 30 50
3 4 3 80 80
2 1 2 10 10
1 3 2 10 50
110
【数据范围】
1 ≤ m, N ≤ 10,0 ≤ Pi , Ri ≤ 100, Pi ≤ Ri (1 ≤ i ≤ m)。
求思路和代码讲解
1 #include<iostream> 2 using namespace std; 3 int m,n,sum=0,minn=999999999,k=0,f=1,maxn=0; 4 int a[1001],b[1001],c[1001],p[1001],r[1001]; 5 int book[1001]; 6 int dfs(int x,int y) 7 { 8 int i; 9 for(i=1;i<=n;i++) 10 { 11 if(a[i]==x && book[b[i]]<=maxn) 12 { 13 book[b[i]]++; 14 if(y>=c[i]) 15 { 16 sum+=p[i]; 17 k=1; 18 } 19 else 20 { 21 sum+=r[i]; 22 k=2; 23 } 24 if(b[i]==m) 25 { 26 if(sum<minn) 27 { 28 minn=sum; 29 f=0; 30 } 31 } 32 else dfs(b[i],y+1); 33 if(k==1) sum-=p[i]; 34 else sum-=r[i]; 35 book[b[i]]--; 36 } 37 } 38 } 39 int main() 40 { 41 cin>>m>>n; 42 int i; 43 for(i=1;i<=n;i++) 44 { 45 cin>>a[i]>>b[i]>>c[i]>>p[i]>>r[i]; 46 if(c[i]>maxn) maxn=c[i]; 47 } 48 book[1]=1; 49 dfs(1,1); 50 if(f==1) cout<<"impossible"; 51 else cout<<minn; 52 return 0; 53 }
刚开始还以为是最短路结果打了一遍发现不对,然后一看数据范围就明白了这是个搜索
然后看注释吧
1 #include<cstdio> 2 #define INF 19260817 3 int n,m,minc=INF,vis[11];//vis表达有没有到过这个点,用来判断Ci 4 //邻接表,前面五个数组分别表示ai,bi,ci,pi,ri 5 int head[11],to[11],req[11],P[11],R[11],nxt[11],idx; 6 inline void addEdge(int u,int v,int v2,int p,int r) 7 { 8 to[++idx]=v;req[idx]=v2; 9 P[idx]=p;R[idx]=r; 10 nxt[idx]=head[u];head[u]=idx; 11 } 12 //由样例数据范围很小可知可以暴力dfs+剪枝 13 void dfs(int u,int cnt) 14 { 15 if(u==n)//边界 16 { 17 if(cnt<minc) minc=cnt; 18 return; 19 } 20 if(cnt>=minc) return;//剪枝 21 vis[u]=1; 22 for(register int e=head[u];e;e=nxt[e])//枚举 23 { 24 int tmp=cnt; 25 if(vis[req[e]]) tmp+=P[e]; 26 else tmp+=R[e]; 27 dfs(to[e],tmp); 28 } 29 vis[u]=0; 30 } 31 32 int main() 33 { 34 //读入数据 35 scanf("%d%d",&n,&m); 36 for(register int i=1;i<=m;i++) 37 { 38 int u,v,v2,p,r;scanf("%d%d%d%d%d",&u,&v,&v2,&p,&r); 39 addEdge(u,v,v2,p,r); 40 } 41 dfs(1,0); 42 //输出数据 43 if(minc==INF) printf("impossible\n"); 44 else printf("%d\n",minc); 45 return 0; 46 }