题目链接:http://poj.org/problem?id=1724
思路:
有限制的最短路,或者说是二维状态吧,在求最短路的时候记录一下花费即可。一开始用SPFA写的,900MS险过啊,然后改成Dijkstra+priority_queue,60MS,orz.
SPFA:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 #define MAXN 104 9 #define inf 1<<30 10 typedef pair<int,int>Pair; 11 12 struct Edge{ 13 int v,w,c; 14 Edge(int vv,int ww,int cc):v(vv),w(ww),c(cc){} 15 }; 16 17 vector<vector<Edge> >map; 18 int dist[MAXN][MAXN*MAXN];//在点i花费j的最短路径 19 bool mark[MAXN][MAXN*MAXN]; 20 int k,n,m,MIN; 21 22 bool SPFA() 23 { 24 memset(mark,false,sizeof(mark)); 25 for(int i=1;i<=n;i++) 26 for(int j=0;j<=k+2;j++) 27 dist[i][j]=inf; 28 queue<Pair>Q; 29 Q.push(make_pair(1,0)); 30 dist[1][0]=0; 31 mark[1][0]=true; 32 while(!Q.empty()){ 33 Pair pp=Q.front(); 34 Q.pop(); 35 int u=pp.first,c=pp.second; 36 mark[u][c]=false; 37 for(int i=0;i<map[u].size();i++){ 38 int v=map[u][i].v; 39 int w=map[u][i].w; 40 int cc=map[u][i].c+c; 41 if(cc>k)continue; 42 if(dist[u][c]+w<dist[v][cc]){ 43 dist[v][cc]=dist[u][c]+w; 44 if(!mark[v][cc]){ 45 mark[v][cc]=true; 46 Q.push(make_pair(v,cc)); 47 } 48 } 49 } 50 } 51 MIN=inf; 52 for(int i=0;i<=k;i++)MIN=min(MIN,dist[n][i]); 53 return MIN<inf; 54 } 55 56 int main() 57 { 58 int u,v,w,c; 59 while(~scanf("%d%d%d",&k,&n,&m)){ 60 map.clear();map.resize(n+2); 61 while(m--){ 62 scanf("%d%d%d%d",&u,&v,&w,&c); 63 map[u].push_back(Edge(v,w,c)); 64 } 65 if(SPFA()){ 66 printf("%d ",MIN); 67 }else 68 puts("-1"); 69 } 70 return 0; 71 }
Dijkstra+priority_queue:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 #define MAXN 104 9 #define inf 1<<30 10 typedef pair<int,int>Pair; 11 12 struct Edge{ 13 int v,w,c; 14 Edge(int vv,int ww,int cc):v(vv),w(ww),c(cc){} 15 }; 16 17 struct Node{ 18 int u,dd,cost; 19 bool operator < (const Node &p) const { 20 if(p.dd==dd)return p.cost<cost; 21 return p.dd<dd; 22 } 23 }; 24 25 vector<vector<Edge> >map; 26 int k,n,m,MIN; 27 28 bool Dijkstra() 29 { 30 priority_queue<Node>Q; 31 Node p,q; 32 p.u=1,p.dd=0,p.cost=0,MIN=inf; 33 Q.push(p); 34 while(!Q.empty()){ 35 p=Q.top(); 36 Q.pop(); 37 int u=p.u,dd=p.dd,cost=p.cost; 38 if(u==n){ MIN=dd;break; } 39 for(int i=0;i<map[u].size();i++){ 40 int v=map[u][i].v,w=map[u][i].w,c=map[u][i].c; 41 if(cost+c<=k){ 42 q.u=v;q.dd=dd+w;q.cost=cost+c; 43 Q.push(q); 44 } 45 } 46 } 47 return MIN<inf; 48 } 49 50 51 int main() 52 { 53 int u,v,w,c; 54 while(~scanf("%d%d%d",&k,&n,&m)){ 55 map.clear();map.resize(n+2); 56 while(m--){ 57 scanf("%d%d%d%d",&u,&v,&w,&c); 58 map[u].push_back(Edge(v,w,c)); 59 } 60 if(Dijkstra()){ 61 printf("%d ",MIN); 62 }else 63 puts("-1"); 64 } 65 return 0; 66 } 67