Description
Input
Output
Sample Input
5 6 7 1 2 2 3 2 4 3 3 3 4 2 4 1 3 4 1 4 6 2 1 3 5 2 0 5 4 3 2
Sample Output
11
题意:求征税k内从1到n的最短路。
思路:这题我真不想说了,做了整整一天啦!我承认自己太笨了,只能默默努力了。WA了好多发,然后发现错误后,又T了好多发,改进了好多次,到最后用multimap才水过……唉……
第一种做法:multimap用时250ms
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <list> #include <queue> #include <string> #include <cstring> #include <map> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define M 10010 #define INF 10000000 using namespace std; typedef long long ll; int k,n,r,MIN=INF; multimap<int,int>z; multimap<int,int>::iterator it; struct abc { int t,val,way; bool operator < (const struct abc a)const { if(val==a.val) return a.way<way; return a.val<val; } }; struct ab { int s,d,l,t; //刚开始没有用这个结构体,用的是二维数组代替的,T了好多发才改成multiset了才加了这个结构体 }e[M]; void dijkstra() { priority_queue<abc>q; //优先队列节省点时间,因为每次出队都是从最小值开始的,所以比较快 abc s1,s2,s3; s1.t=1; s1.val=0; s1.way=0; q.push(s1); while(!q.empty()) { int n1,t1,val,i,way,num; s2=q.top(); q.pop(); n1=s2.t; val=s2.val; way=s2.way; if(n1==n) {MIN=val;break;} //因为是优先队列,所以只要到n就找到最小值了 num=z.count(n1); it=z.find(n1); //找到e[s].s在第几行,即地址,本来想用哈希思想做的,但是转来转去比较头晕,所以用了笨方法的STL for(i=0;i<num;i++,it++) { t1=(*it).second; //取出e[s]. if(way+e[t1].t<=k) { s3.t=e[t1].d; s3.val=val+e[t1].l; s3.way=way+e[t1].t; q.push(s3); } } } if(MIN==INF) printf("-1\n"); else printf("%d\n",MIN); } int main() { int s,d,l,t,i; scanf("%d%d%d",&k,&n,&r); for(i=0;i<r;i++) { scanf("%d%d%d%d",&e[i].s,&e[i].d,&e[i].l,&e[i].t); z.insert(pair<int,int>(e[i].s,i)); } dijkstra(); return 0; }
第二种做法:邻接表,用时32ms
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <list> #include <queue> #include <string> #include <cstring> #include <map> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define M 10010 #define INF 10000000 using namespace std; typedef long long ll; int n,m,i,u,v,w,d,c,cost,tot,ans=INF,head[M]; struct node { int n,d,c; bool operator < (const struct node a)const { if(a.d == d) return a.c < c; return a.d < d; } }s,x,y; struct edge { int u,v,w,c,next; } e[M]; void dijkstra() { priority_queue<node>q; s.n = 1; s.d = 0; s.c = 0; q.push(s); while(!q.empty()) { x = q.top(); q.pop(); u = x.n; d = x.d; if(u == n) {ans = x.d; break;} for(i=head[u]; i!=-1; i=e[i].next) { v = e[i].v; w = e[i].w; c = e[i].c; if(x.c + c <= cost) //在花费允许的范围内可以去到这个点 { y.n = v; y.d = d + w; y.c = x.c + c; q.push(y); } } } if(ans==INF) printf("-1\n"); else printf("%d\n",ans); } int main() { scanf("%d%d%d",&cost,&n,&m); memset(head,-1,sizeof(head)); tot = 0; for(i=0;i<m;i++) { scanf("%d%d%d%d",&u,&v,&w,&c); e[tot].u = u; e[tot].v = v; e[tot].w = w; e[tot].c = c; e[tot].next = head[u]; //邻接表 head[u] = tot++; } dijkstra(); return 0; }