坐井观天

In the name of dream

导航

POJ 3411 最短路问题(bfs+优先队列+计数)

Posted on 2012-06-26 21:30  一毛_  阅读(231)  评论(0编辑  收藏  举报

题目链接: 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率从后往前数,从来都是第一,表示我还经常开小号调试代码然后用这个大号交,伤不起!

 

代码:

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