每个点有2种到法,一种是直接过去,一种是事先经过了c点,然后再去b点就可以交少一点钱。
所以说,不能简单的标记一个点去了没去,而应该标记为去了几次,如果一个点重复去了n次,那就肯定是没必要的。
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> #include<vector> #include<iostream> using namespace std; struct node { int a,b,c,p,r; }road[11]; vector<node> point[11]; //以i为出发点的边 int n,m,ans; int vis[11]; void dfs(int k,int cost) { if(cost>ans) return; if(k==n) { ans=min(ans,cost); return; } for(int i=0;i<point[k].size();i++) { node p=point[k][i]; if(vis[p.b]<=n) { vis[p.b]++; if(vis[p.c]) dfs(p.b,cost+p.p); else dfs(p.b,cost+p.r); vis[p.b]--; } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { ans=0x3f3f3f3f; for(int i=1;i<=n;i++) point[i].clear(); for(int i=1;i<=m;i++) { scanf("%d%d%d%d%d",&road[i].a,&road[i].b,&road[i].c,&road[i].p,&road[i].r); point[road[i].a].push_back(road[i]); } memset(vis,0,sizeof(vis)); vis[1]=1; dfs(1,0); if(ans==0x3f3f3f3f) printf("impossible\n"); else printf("%d\n",ans); } return 0; }