题意:中文题目就不多解释了。
思路:Dijkstra优化。其实不优化也可以吧。首先就是保存路径。之后对每个点跑Dijkstra,然后找出到顶点1的最小值。刚开始没认真读题,以为只是相互交换的两个人之间的顶级差异只要在m范围就可以了,结果WA到爆炸。
题目链接:http://poj.org/problem?id=1062
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> using namespace std; #define MAX 105 const int INF=1e9+10; typedef pair<int,int> P; int dis[MAX]; int d[MAX]; int x[MAX]; int p[MAX]; int minnn[MAX]; int maxxx[MAX]; int MAXX; int MINN; int m,n; int minn; struct Edge { int v; //int next; int w; //Edge(int v,int w):v(v),w(w){} }; struct Node { int w; int v; int maxx; int minn; Node(int w,int v,int maxx,int minn):w(w),v(v),maxx(maxx),minn(minn){} bool operator < (const Node &a) const { return w<a.w; } }; Edge edge[MAX][MAX]; int head[MAX]; vector<Edge> G[MAX]; //Edge edge1[MAX*MAX]; void Dijkstra(int s) { for(int i=1;i<=n;i++) { d[i]=dis[i]; } priority_queue<Node> que; que.push(Node(d[s],s,x[s],x[s])); while(!que.empty()) { Node pp=que.top(); que.pop(); int v=pp.v; if(d[v]<pp.w) continue; for(int i=0;i<G[v].size();i++) { int to=G[v][i].v; int w=G[v][i].w; if(d[to]>d[v]+w&&abs(x[to]-pp.minn)<=m&&abs(x[to]-pp.maxx)<=m) { MINN=min(x[to],pp.minn); MAXX=max(x[to],pp.maxx); //maxxx[to]=max(maxxx[i],maxxx[v]); d[to]=d[v]+w; que.push(Node(d[to],to,MAXX,MINN)); } } } minn=min(minn,d[1]); return ; } int main() { scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) { scanf("%d%d%d",&dis[i],&x[i],&p[i]); for(int j=1;j<=p[i];j++) scanf("%d%d",&edge[i][j].v,&edge[i][j].w); } //int cnt=0; //memset(head,-1,sizeof(head)); for(int i=1;i<=n;i++) { for(int j=1;j<=p[i];j++) { int v=edge[i][j].v; int w=edge[i][j].w; if(abs(x[i]-x[v])<=m) { Edge e; e.v=i; e.w=w; G[v].push_back(e); } } } minn=INF; for(int i=1;i<=n;i++) { Dijkstra(i); } printf("%d\n",minn); return 0; }

浙公网安备 33010602011771号