标签:blog http io ar os sp for on 2014
题目链接:传送门
题意:n个城市,m条道路,要求1--N的最小花费。规定从a城市到城市的花费有两种:如果之前到过c,花费为p,否则花费为r。注意:道路是双向的。
难点:可能a到b有多条路而且花费不同这样的话邻接矩阵会错;有人可能深搜的时候会让每个城市只走一次(DFS惯性思维),但这道题不一样,因为到达下一个城市之前可能需要先到另外一个城市以降低花费。这样的话可以标记每个城市访问过的次数,可以设定让它不超过10次,网上说是3次其实这都无所谓,因为可以加一个最优化剪枝那样就算设为20次也能过(设为20的时候我跑过219ms,10次是0ms)最优化剪枝就是如果当前答案大于已经搜到最优答案,剪掉。
注意有可能无解。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cctype> #include <vector> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define maxn 360 #define _ll __int64 #define ll long long #define INF 0x3f3f3f3f #define Mod 1000000007 #define pp pair<int,int> #define ull unsigned long long #define max(x,y) ( ((x) > (y)) ? (x) : (y) ) #define min(x,y) ( ((x) > (y)) ? (y) : (x) ) using namespace std; struct node { int u,c,wa,wb; node (int a,int b,int x,int y) { u=a;c=b;wa=x;wb=y; } }; vector <node> eg[12]; int ok,ma[12][12][2],n,m,vis[12],ans; void init() { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) eg[i].clear(); } void dfs(int u,int s) { if(s>ans)return ; if(u==n) { ok=1;ans=min(ans,s); return ; } for(int i=0;i<eg[u].size();i++) { int v=eg[u][i].u; if(vis[v]<=20) { vis[v]++; if(vis[eg[u][i].c]) dfs(v,s+eg[u][i].wa); else dfs(v,s+eg[u][i].wb); vis[v]--; } } } int main() { int u,v,c,wa,wb; while(~scanf("%d%d",&n,&m)) { init(); while(m--) { scanf("%d%d%d%d%d",&u,&v,&c,&wa,&wb); eg[u].push_back(node(v,c,wa,wb)); } ans=INF;ok=0;dfs(1,0); if(ok) printf("%d\n",ans); else puts("impossible"); } return 0; }
标签:blog http io ar os sp for on 2014
原文地址:http://blog.csdn.net/qq_16255321/article/details/41481553