题目链接: http://poj.org/problem?id=3411
题目大意:
给定n个点,m条边(n,m<=10),每条边ai,bi,ci,pi,ri表示从ai到bi有边,付费方式两种:
1、 之前在ci点付费pi,
2、 到达bi点再付费ri;
求1到n的最小花费;
分析:
纯属乱搞,状态( u, cost, node ),u表示当前节点,cost表示此时花费,node表示已经经过的点(二进制表示),用优先队列+bfs过。
开始tle了,后来干脆给每条边开了一个cnt计数,初始化为0,然后没访问边一次,cnt++,当cnt>20时不访问,居然ac了!!!
注意 pi <= ri,这里可以省可以挑更优的状态,具体见代码。
好吧,今天做了几个最短路的水题,把poj帐号刷上了310了,发现:
1541 | yuanchuanshun | 310 |
1071 |
AC率从后往前数,从来都是第一,表示我还经常开小号调试代码然后用这个大号交,伤不起!
代码:

1 /*3411 Accepted 256K 0MS C++ 1936B 2012-06-26 21:22:14*/ 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <iostream> 6 #include <algorithm> 7 #include <vector> 8 #include <queue> 9 using namespace std; 10 11 #define mpair make_pair 12 #define pii pair<int,int> 13 #define MM(a,b) memset(a,b,sizeof(a)); 14 typedef long long lld; 15 typedef unsigned long long u64; 16 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;} 17 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;} 18 #define maxn 12 19 20 int n,m,top; 21 struct Edge{ 22 int v,ci,pi,ri,cnt; 23 Edge *next; 24 } *adj[maxn], edge[maxn]; 25 void Addedge(int u,int v,int ci,int pi,int ri){ 26 Edge *p= &edge[top++]; 27 p->v=v, p->ci=ci, p->pi=pi, p->ri=ri, p->cnt=0, p->next= adj[u], adj[u]= p; 28 } 29 30 struct Node{ 31 int u, cost, node; 32 Node(int u_,int cost_,int node_){u=u_,cost=cost_,node=node_;} 33 bool operator<(Node a)const{ 34 return cost > a.cost; 35 } 36 }; 37 priority_queue<Node>Q; 38 39 int bfs(int st){ 40 while( !Q.empty() ) Q.pop(); 41 Q.push( Node( st, 0, 1<<st ) ); 42 43 while( !Q.empty() ){ 44 Node a= Q.top(); Q.pop(); 45 int u= a.u, cost= a.cost, node= a.node; 46 if( u==n ) return cost; 47 for(Edge *p= adj[u];p;p= p->next){ 48 if( ++ p->cnt >20 ) continue; ///!!! 49 50 int v= p->v; 51 if( (node&( 1<<(p->ci) )) ) 52 Q.push( Node( v, cost + p->pi, node | (1<<v) ) ); /// pi <= ri; 53 else 54 Q.push( Node( v, cost + p->ri, node | (1<<v) ) ); 55 } 56 } 57 return -1; 58 } 59 60 int main() 61 { 62 //freopen("poj3411.in","r",stdin); 63 while( cin>>n>>m ){ 64 top= 0; 65 MM( adj, 0 ); 66 while(m--){ 67 int u,v,ci,pi,ri; 68 scanf("%d%d%d%d%d", &u, &v, &ci, &pi, &ri); 69 Addedge( u, v, ci, pi, ri ); 70 } 71 int ans= bfs(1); 72 if( -1==ans ) puts("impossible"); 73 else cout<< ans <<endl; 74 } 75 }