poj 3411 Paid Roads(dfs+标记路径->求最少花费)
2017-11-14 17:52
447 查看
Paid Roads
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit Status
Description
A network of m roads connects N cities (numbered from 1 to N). There may be more than one road connecting one city with another. Some of the roads are paid. There are two ways to pay for travel on a paid
road i from city ai to city bi:
in advance, in a city ci (which may or may not be the same as ai);
after the travel, in the city bi.
The payment is Pi in the first case and Ri in the second case.
Write a program to find a minimal-cost route from the city 1 to the city N.
Input
The first line of the input contains the values of N and m. Each of the following m lines describes one road by specifying the values of ai, bi, ci, Pi, Ri (1
≤ i≤ m). Adjacent values on the same line are separated by one or more spaces. All values are integers, 1 ≤ m, N ≤ 10, 0 ≤ Pi , Ri ≤ 100, Pi ≤ Ri (1
≤ i ≤m).
Output
The first and only line of the file must contain the minimal possible cost of a trip from the city 1 to the city N. If the trip is not possible for any reason, the line must contain the word ‘impossible’.
Sample Input
Sample Output
借鉴:
这题难点在于“城市与城市之间可能存在多条路径”:
1、 输入数据时可能会出现多条 从城市a到城市b的路径信息,但是费用有所差别;
2、 对于 从城市a到城市b 的同一条路径,允许重复走。
有人会问,重复走同一条路径有什么意义?单纯增加费用而已,为什么不能标记所有路径,每条路只允许走一次,这样费用不是更少么?
我开始也是陷入了这种思维,但是这种想法其实“对一半,错一半”。
先来看一组数据:
6 5
1 2 1 10 10
2 3 4 10 100
2 4 2 15 15
4 1 1 12 12
3 6 6 10 10
如果每条路只允许走一次,那么方案只有1个:
1à2à3à6 共135元
但这组数据的正确答案是67元。为什么?正确的方案如下:
1à2à4à1à2à3à6 共67元
显然1à2重复走了一次,目的是为了先到达城市4,从而使得2à3这段路的费用从100缩减到10元。
看到这里很多同学好像就恍然大悟,但是问题马上又来了。如果同一条路允许重复走,那么就不能标记了,但一旦不标记,失去了搜索的限制条件,DFS就无法结束,不是陷入死循环了?
我刚才说这种思路“对一半,错一半”,“对”是对在“重复走会增加费用”,“错”是错在“重复走的对象不是某一条路,而是某一个环路”。在同一个环路重复走才会真正增加费用。但是标记环路是很麻烦的,那么能不能根据某一条路或某一个城市重复走过的次数来判断当前所走的方案已经出现了环路? 答案是可以的。
上述的例子已经验证过了,同一条路可以重复走,但是不能无限重复走,重复的次数是有限的。那么应该重复多少次才合理?这与m值有关。题目的m值范围为<=10,那么当人一个城市被到达的次数若 >3次(不包括3),所走的方案必然出现了环路(网上的同学称之为“闸数”)。
因此只需把bool vist[] 修改为 int vist[] 进行标记,本题就能解决了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int N = 16;
struct node
{
int b, c, p, r;
};
vector<node>q
;
const int inf = 0x3f3f3f3f;
int vis
;
int ans, n, m;
void dfs(int u,int sum)
{
vis[u]++;
if(u==n)
{
if(ans>sum)
ans=sum;
return ;
}
if(sum>ans)
return ;
for(int i=0;i<q[u].size();i++)
{
int v1=q[u][i].b, v2=q[u][i].c;
if(vis[v1]<=3)
{
int cost=q[u][i].r;
if(vis[v2])
cost=min(cost,q[u][i].p);
dfs(v1,sum+cost);
vis[v1]--;
}
}
return ;
}
int main()
{
while(scanf("%d %d", &n, &m)!=EOF)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
q[i].clear();
for(int i=0;i<m;i++)
{
int x, y, z, l1, l2;
scanf("%d %d %d %d %d",&x, &y, &z, &l1, &l2);
node e;
e.b=y, e.c=z, e.p=l1, e.r=l2;
q[x].push_back(e);
}
ans=inf;
dfs(1,0);
if(ans<inf)
printf("%d\n",ans);
else
printf("impossible");
}
return 0;
}
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit Status
Description
A network of m roads connects N cities (numbered from 1 to N). There may be more than one road connecting one city with another. Some of the roads are paid. There are two ways to pay for travel on a paid
road i from city ai to city bi:
in advance, in a city ci (which may or may not be the same as ai);
after the travel, in the city bi.
The payment is Pi in the first case and Ri in the second case.
Write a program to find a minimal-cost route from the city 1 to the city N.
Input
The first line of the input contains the values of N and m. Each of the following m lines describes one road by specifying the values of ai, bi, ci, Pi, Ri (1
≤ i≤ m). Adjacent values on the same line are separated by one or more spaces. All values are integers, 1 ≤ m, N ≤ 10, 0 ≤ Pi , Ri ≤ 100, Pi ≤ Ri (1
≤ i ≤m).
Output
The first and only line of the file must contain the minimal possible cost of a trip from the city 1 to the city N. If the trip is not possible for any reason, the line must contain the word ‘impossible’.
Sample Input
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
Sample Output
110
借鉴:
这题难点在于“城市与城市之间可能存在多条路径”:
1、 输入数据时可能会出现多条 从城市a到城市b的路径信息,但是费用有所差别;
2、 对于 从城市a到城市b 的同一条路径,允许重复走。
有人会问,重复走同一条路径有什么意义?单纯增加费用而已,为什么不能标记所有路径,每条路只允许走一次,这样费用不是更少么?
我开始也是陷入了这种思维,但是这种想法其实“对一半,错一半”。
先来看一组数据:
6 5
1 2 1 10 10
2 3 4 10 100
2 4 2 15 15
4 1 1 12 12
3 6 6 10 10
如果每条路只允许走一次,那么方案只有1个:
1à2à3à6 共135元
但这组数据的正确答案是67元。为什么?正确的方案如下:
1à2à4à1à2à3à6 共67元
显然1à2重复走了一次,目的是为了先到达城市4,从而使得2à3这段路的费用从100缩减到10元。
看到这里很多同学好像就恍然大悟,但是问题马上又来了。如果同一条路允许重复走,那么就不能标记了,但一旦不标记,失去了搜索的限制条件,DFS就无法结束,不是陷入死循环了?
我刚才说这种思路“对一半,错一半”,“对”是对在“重复走会增加费用”,“错”是错在“重复走的对象不是某一条路,而是某一个环路”。在同一个环路重复走才会真正增加费用。但是标记环路是很麻烦的,那么能不能根据某一条路或某一个城市重复走过的次数来判断当前所走的方案已经出现了环路? 答案是可以的。
上述的例子已经验证过了,同一条路可以重复走,但是不能无限重复走,重复的次数是有限的。那么应该重复多少次才合理?这与m值有关。题目的m值范围为<=10,那么当人一个城市被到达的次数若 >3次(不包括3),所走的方案必然出现了环路(网上的同学称之为“闸数”)。
因此只需把bool vist[] 修改为 int vist[] 进行标记,本题就能解决了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int N = 16;
struct node
{
int b, c, p, r;
};
vector<node>q
;
const int inf = 0x3f3f3f3f;
int vis
;
int ans, n, m;
void dfs(int u,int sum)
{
vis[u]++;
if(u==n)
{
if(ans>sum)
ans=sum;
return ;
}
if(sum>ans)
return ;
for(int i=0;i<q[u].size();i++)
{
int v1=q[u][i].b, v2=q[u][i].c;
if(vis[v1]<=3)
{
int cost=q[u][i].r;
if(vis[v2])
cost=min(cost,q[u][i].p);
dfs(v1,sum+cost);
vis[v1]--;
}
}
return ;
}
int main()
{
while(scanf("%d %d", &n, &m)!=EOF)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
q[i].clear();
for(int i=0;i<m;i++)
{
int x, y, z, l1, l2;
scanf("%d %d %d %d %d",&x, &y, &z, &l1, &l2);
node e;
e.b=y, e.c=z, e.p=l1, e.r=l2;
q[x].push_back(e);
}
ans=inf;
dfs(1,0);
if(ans<inf)
printf("%d\n",ans);
else
printf("impossible");
}
return 0;
}
相关文章推荐
- Poj 3411 Paid Roads (DFS 特殊标记方法)
- poj 3411Paid Roads(走重复点的dfs )
- poj 3411 Paid Roads很水的DFS
- 多次访问节点的DFS POJ 3411 Paid Roads
- POJ 3411 Paid Roads(dfs)
- POJ 3411 Paid Roads (DFS多次访问节点)
- poj 3411 Paid Roads(dfs)
- POJ 3411 Paid Roads(DFS)
- POJ 3411 Paid Roads(DFS)
- (POJ 3411)Paid Roads <DFS>
- POJ 3411-Paid Roads(DFS)
- POJ 3411 Paid Roads 简单DFS
- poj 3411 Paid Roads (dfs)
- Poj 3411 Paid Roads【Dfs】
- POJ 3411 Paid Roads(DFS)
- poj_3411 Paid Roads(dfs技巧)
- poj 3411 Paid Roads(dfs,可重复访问节点)
- POJ 3411 Paid Roads(DFS)
- poj 3411 Paid Roads -dfs
- poj 3411 Paid Roads(dfs)