http://poj.org/problem?id=3411
题目大意:
n城市 m条路(可能重)
每条路两种情况付费 a b c p r
如果已经经过了c城则可以付费p 否则只能付费r
求从1到n最小花费
思路:
记录各种花费 然后Dfs枚举 但是本题某一点可以多次
不过由于边的数量是最多10 所以某一个点最多经过4此(自己想吧 亲!)
快乐深搜 注意n=1的情况
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<algorithm>
#include<set>
using namespace std;
const int N=11;
const int M=1000000;
struct node
{
bool can;
int cp[N];
int cr;
}road[N][N];
int had[N];
int n,m;
int ans;
void begin()
{
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
road[i][j].can=false;
road[i][j].cr=M;
for(int l=1;l<=n;++l)
{
road[i][j].cp[l]=M;
}
}
}
void Dfs(int a,int sum)
{
for(int b=1;b<=n;++b)
{
if(had[b]<n&&road[a][b].can==true)
{
int temp=road[a][b].cr;
for(int l=1;l<=n;++l)
{
if(had[l]&&road[a][b].cp[l]<temp)
temp=road[a][b].cp[l];
}
if(b==n)
{
ans=min(ans,sum+temp);
}else if(sum+temp<ans)
{
++had[b];
Dfs(b,sum+temp);
--had[b];
}
}
}
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
begin();
while(m--)
{
int a,b,c,p,r;
scanf("%d %d %d %d %d",&a,&b,&c,&p,&r);
road[a][b].can=true;
road[a][b].cp[c]=min(road[a][b].cp[c],p);
road[a][b].cr=min(road[a][b].cr,r);
}
if(n==1)
{
printf("0\n");
continue;
}
ans=M;
memset(had,0,sizeof(had));
had[1]=1;
Dfs(1,0);
if(ans==M)
printf("impossible\n");
else
printf("%d\n",ans);
}
return 0;
}