首页 > 代码库 > POJ 4046 Sightseeing
POJ 4046 Sightseeing
最短路的变形,因为要加上最大的点权,所以只能枚举以每一个点为起始点且为最大点权的最短路。
则对于每次询问有 Min = min(Min,dis[i][s] + dis[i][t] + val[i])。
然后此题需要好多细节上的优化。
比如,能用全局就用全局。
然后又重新搞了一遍SPFA。。。。竟然不会写了。。。。
以前写最短路一直在用bfs + priority_queue,不过竟然比spfa慢。。。
-------------------------updata------------------------------
其实bfs + priority_queue还是蛮可以的 . . . .一定是上次写挫了。。。。最后面附上bfs+priority_queue的代码。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long #define _LL __int64 #define INF 1e18 #define Mod 6000007 using namespace std; LL val[1010]; struct N { LL w; int v,next; }edge[40010]; int head[1010]; int Top; void Link(int u,int v,LL w) { edge[Top].v = v; edge[Top].w = w; edge[Top].next = head[u]; head[u] = Top++; } LL dis[1010]; bool mark[1010]; queue<int> q; void Cal(int s,int n) { memset(mark,false,sizeof(bool)*(n+2)); int f,t; for(int i = 1;i <= n; ++i) dis[i] = INF; f = s; dis[s] = 0; q.push(f); mark[s] = true; while(q.empty() == false) { f = q.front(); q.pop(); mark[f] = false; for(int p = head[f];p != -1; p = edge[p].next) { if(val[edge[p].v] > val[s]) continue; if(dis[f] + edge[p].w < dis[edge[p].v]) { dis[edge[p].v] = dis[f] + edge[p].w; if(mark[edge[p].v] == false) { mark[edge[p].v] = true; t = edge[p].v; q.push(t); } } } } } int S[20010],T[20010]; LL Min[20010]; int main() { int n,m,i,j,u,v; LL w; while(scanf("%d %d",&n,&m) && (n||m)) { memset(head,-1,sizeof(int)*(n+2)); Top = 0; for(i = 1;i <= n; ++i) { scanf("%lld",&val[i]); } for(i = 1;i <= m; ++i) { scanf("%d %d %lld",&u,&v,&w); Link(u,v,w); Link(v,u,w); } scanf("%d",&m); for(i = 0;i < m; ++i) { scanf("%d %d",&S[i],&T[i]); Min[i] = INF; } for(i = 1;i <= n; ++i) { Cal(i,n); for(w = 0;w < m; ++w) { Min[w] = min(Min[w],dis[S[w]] + dis[T[w]] + val[i]); } } for(i = 0;i < m; ++i) { if(Min[i] == INF) printf("-1\n"); else printf("%lld\n",Min[i]); } printf("\n"); } return 0; }
bfs+priority_queue
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long #define _LL __int64 #define INF 1e18 #define Mod 6000007 using namespace std; LL val[1010]; struct N { LL w; int v,next; }edge[40010]; int head[1010]; int Top; void Link(int u,int v,LL w) { edge[Top].v = v; edge[Top].w = w; edge[Top].next = head[u]; head[u] = Top++; } LL dis[1010]; bool mark[1010]; struct Q { int v; LL cost; bool operator < (const Q &a) const { return a.cost < cost; } }; priority_queue<Q> q; void Cal(int s,int n) { memset(mark,false,sizeof(bool)*(n+2)); Q f,t; for(int i = 1;i <= n; ++i) dis[i] = INF; f.v = s; f.cost = 0; q.push(f); while(q.empty() == false) { f = q.top(); q.pop(); if(mark[f.v]) continue; mark[f.v] = true; dis[f.v] = f.cost; for(int p = head[f.v];p != -1; p = edge[p].next) { if(val[edge[p].v] > val[s]) continue; t.v = edge[p].v; t.cost = edge[p].w + f.cost; if(dis[t.v] > t.cost) { dis[t.v] = t.cost; q.push(t); } } } } int S[20010],T[20010]; LL Min[20010]; int main() { int n,m,i,j,u,v; LL w; while(scanf("%d %d",&n,&m) && (n||m)) { memset(head,-1,sizeof(int)*(n+2)); Top = 0; for(i = 1;i <= n; ++i) { scanf("%lld",&val[i]); } for(i = 1;i <= m; ++i) { scanf("%d %d %lld",&u,&v,&w); Link(u,v,w); Link(v,u,w); } scanf("%d",&m); for(i = 0;i < m; ++i) { scanf("%d %d",&S[i],&T[i]); Min[i] = INF; } for(i = 1;i <= n; ++i) { Cal(i,n); for(w = 0;w < m; ++w) { Min[w] = min(Min[w],dis[S[w]] + dis[T[w]] + val[i]); } } for(i = 0;i < m; ++i) { if(Min[i] == INF) printf("-1\n"); else printf("%lld\n",Min[i]); } printf("\n"); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。