有n座城市和m(1<=n,m<=10)条路。现在要从城市1到城市n。有些路是要收费的,从a城市到b城市,如果之前到过c城市,那么只要付P的钱,如果没有去过就付R的钱。求的是最少要花多少钱。
如下例:
4 4
1 2 1 10 10
2 3 2 10 10
3 1 3 10 10
2 4 3 10 90
显然花费最小的路为 1 > 2 > 3 > 1 > 2 > 4。
即花费最小的路中可能存在环,也就是说在最优路中,可能会经过某个点很多次。
因为 n <= 10,所以任意一点最多会存在于不同的四个环中,换言之,每个点最多只会走过四次,我们成这个次数为”闸数“。
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <stack>
#define LL long long
#define ULL unsigned long long
#define PI (acos(-1.0))
#define EPS (1e-10)
#pragma comment(linker,"/STACK:102400000,1024000")
using namespace std;
struct N
{
int a,b,c,p,r,next;
}edge[12];
int head[11];
int Top;
void Link(int a,int b,int c,int p,int r)
{
edge[Top].a = a;
edge[Top].b = b;
edge[Top].c = c;
edge[Top].p = p;
edge[Top].r = r;
edge[Top].next = head[a];
head[a] = Top++;
}
bool me[11][11][2];
int mp[11];
int rv[11];
int dis[11];
int MAXN,Min;
void dfs(int s,int dis)
{
if(dis >= Min)
return ;
if(s == MAXN)
{
Min = dis;
return ;
}
mp[s]++;
for(int p = head[s];p != -1;p = edge[p].next)
{
if(rv[edge[p].b] < 4)
{
rv[edge[p].b]++;
if(mp[edge[p].c] != 0)
{
dfs(edge[p].b,dis+edge[p].p);
}
else if(mp[edge[p].c] == 0)
{
dfs(edge[p].b,dis+edge[p].r);
}
rv[edge[p].b]--;
}
}
mp[s]--;
}
int main()
{
int n,m,a,b,c,p,r,i;
while(scanf("%d %d",&n,&m) != EOF)
{
memset(head,-1,sizeof(head));
Top = 0;
for(i = 0;i < m; ++i)
{
scanf("%d %d %d %d %d",&a,&b,&c,&p,&r);
Link(a,b,c,p,r);
}
memset(mp,0,sizeof(mp));
memset(rv,0,sizeof(rv));
Min = 10000000;
MAXN = n;
dfs(1,0);
if(Min == 10000000)
{
printf("impossible\n");
}
else
{
printf("%d\n",Min);
}
}
return 0;
}
原文:http://blog.csdn.net/zmx354/article/details/19348559