hdu4725 The Shortest Path in Nya Graph【最短路+建图】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4297574.html ---by 墨染之樱花
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4725
题目描述:给一张图,每个点(1~N)都属于一个层(1~N),比如点1在第5层,点3在第4层,点4也在第5层。任何在x层的点都可以移动到x+1层和x-1层中的任何点上,并且需要耗费C的权值。除此之外,另外再给出M条带权无向边。求点1到点N的最短路
思路:此图数据量比较大,暴力建图不可取。可以将层也抽象化成点,也就是一共有N个点节点和N个层节点,然后按照层与层之间(双向,权值C)、点与点之间(即后来给的M条边)、点与相对应的层之间(层指向点,权值0),点与对应层的相邻层之间(点指向层,权值C)建图,最后求最短路即可
#include <iostream> #include <ios> #include <iomanip> #include <functional> #include <algorithm> #include <vector> #include <sstream> #include <list> #include <queue> #include <deque> #include <stack> #include <string> #include <set> #include <map> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <cstring> #include <climits> using namespace std; #define XINF INT_MAX #define INF 1<<30 #define MAXN 200000+10 #define eps 1e-8 #define zero(a) fabs(a)<eps #define sqr(a) ((a)*(a)) #define MP(X,Y) make_pair(X,Y) #define PB(X) push_back(X) #define PF(X) push_front(X) #define REP(X,N) for(int X=0;X<N;X++) #define REP2(X,L,R) for(int X=L;X<=R;X++) #define DEP(X,R,L) for(int X=R;X>=L;X--) #define CLR(A,X) memset(A,X,sizeof(A)) #define IT iterator #define PI acos(-1.0) #define test puts("OK"); #define _ ios_base::sync_with_stdio(0);cin.tie(0); typedef long long ll; typedef pair<int,int> PII; typedef priority_queue<int,vector<int>,greater<int> > PQI; typedef vector<PII> VII; typedef vector<int> VI; #define X first #define Y second int V,M,C; VII G[MAXN]; int d[MAXN]; bool cnt[MAXN]; int level[MAXN]; void addedge(int u,int v,int c) { G[u].PB(MP(v,c)); G[v].PB(MP(u,c)); } void dijkstra(int s) { priority_queue<PII,VII,greater<PII> > Q; fill(d,d+2*V,INF); d[s]=0; Q.push(MP(d[s],s)); while(!Q.empty()) { PII p=Q.top();Q.pop(); int v=p.Y; if(d[v]<p.X) continue; REP(i,G[v].size()) { PII e=G[v][i]; if(d[e.X]>d[v]+e.Y) { d[e.X]=d[v]+e.Y; Q.push(MP(d[e.X],e.X)); } } } } int main() {_ int T,k=1; scanf("%d",&T); while(T--) { CLR(G,0);CLR(cnt,0); scanf("%d%d%d",&V,&M,&C); REP(i,V) { int x; scanf("%d",&x); x--; level[i]=x; cnt[V+x]=1; } REP2(i,V,2*V-2) if(cnt[i] && cnt[i+1]) if(i+1<2*V && cnt[i+1]) addedge(i,i+1,C); REP(i,V) { G[V+level[i]].PB(MP(i,0)); if(level[i]-1>=0) G[i].PB(MP(V+level[i]-1,C)); if(level[i]+1<V) G[i].PB(MP(V+level[i]+1,C)); } REP(i,M) { int u,v,w; scanf("%d%d%d",&u,&v,&w); u--;v--; addedge(u,v,w); } dijkstra(0); printf("Case #%d: %d\n",k++,d[V-1]==INF?-1:d[V-1]); } return 0; }