题目大意:给定n个城市从1到n,给定从a到b这条路的付款方式,可以在b处付款,但是付款的钱数为Ri,或者在走这条路的时候已经到过城市c,可以在c处付这条路的钱,钱数为Pi,求从1到n路途中付款的最少的钱!
思路:用的是深搜,但是注意要控制条件,因为是要求的钱数最少,所以可以在一条路上多走几次是允许的,我在着方面WA了n次啊,后来看了别人的测试数据才过的!题中没有给定限制条件一条路可以走几次,我限制可以走两次时是0ms过的,三次就是110ms,如果题再给些什么数据的话,可能三次也不会过了!!!
下面是代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
using namespace std;
#define rep(i,n) for(i=0; i<(n); i++)
#define repf(i,n,m) for(i=(n); i<=(m); i++)//正循环的
#define repd(i,n,m) for(i=(n); i>=(m); i--) //负循环的
#define fab(a) (a)>0?(a):0-(a)
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
#define ll __int64
#define arc(a) (a)*(a)
#define inf 10000000 //最大值的
#define exp 0.0000001 //浮点型的
#define N 15 //记录开的数组
int n,m,len;
int sum;
int flag[N];
struct node
{
int i,y,adv,p,r;//p为提前预支的花费
int pre;
}a[N];
int pre[N];
int vis[N];
void addpage(int i,int a1,int b1,int c1,int p1,int r1)
{
a[len].i=i;
a[len].y=b1;
a[len].adv=c1;
a[len].p=p1;
a[len].r=r1;
a[len].pre=pre[a1];
pre[a1]=len++;
}
void dfs(int s,int t)
{
if(s==n)
{
sum=min(sum,t);
return ;
}
int i,j;
for(i=pre[s];i!=-1; i=a[i].pre)
{
j=a[i].i;
if(vis[j]<3)
{
flag[s]++;
vis[j]++;
if(flag[a[i].adv]>0)
{
dfs(a[i].y,t+a[i].p);
}
else
{
dfs(a[i].y,t+a[i].r);
}
vis[j]--;
flag[s]--;
}
}
}
int main()
{
int a1,b1,c1,p1,r1;
int i,j;
while(~scanf("%d%d",&n,&m))
{
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
memset(flag,0,sizeof(flag));
len=1;
sum=INT_MAX;
repf(i,1,m)
{
scanf("%d%d%d%d%d",&a1,&b1,&c1,&p1,&r1);
addpage(i,a1,b1,c1,p1,r1);
}
for(i=pre[1];i!=-1;i=a[i].pre)//从1开始搜索的
{
flag[1]++;
j=a[i].i;
vis[j]++;//代表第j个路已经用过了
if(flag[a[i].adv]==true)
dfs(a[i].y,a[i].p);
else
dfs(a[i].y,a[i].r);
vis[j]--;
flag[1]--;
}
if(n==1)
sum=0;
if(sum==INT_MAX)
printf("impossible\n");
else
printf("%d\n",sum);
}
return 0;
}