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; }