ACM 最短路徑 POJ1062題解
阿新 • • 發佈:2019-02-07
解題思路:建立源點0,最後我們求的是到點1的最短路徑。因為有等級限制,我們只需將符合等級要求間的點設定為連通的,而不符合的點設定為不連通的。這裡需要依次列舉最小等級的點。
下面是程式碼:
#include<iostream> #include<stdio.h> #include<string.h> #include<map> #include<vector> #include<set> #include<stack> #include<queue> #include<algorithm> #include<stdlib.h> using namespace std; #define MAX(a,b) (a > b ? a : b) #define MIN(a,b) (a < b ? a : b) #define mem(a) memset(a,0,sizeof(a)) #define MAXN 105 #define INF 1000000007 int Price[MAXN],Edge[MAXN][MAXN],Level[MAXN]; int vis[MAXN], d[MAXN]; int N,M,ans; void init() { mem(Price); mem(Level); for(int i=0;i<=N;i++) { for(int j=0;j<=N;j++) { Edge[i][j] = INF;//初始化每條邊都是不連通的 } } } void read() { int i,j,X,T,TP; for(i=1;i<=N;i++) { scanf("%d%d%d",&Price[i], &Level[i], &X); for(j=0;j<X;j++) { scanf("%d %d", &T, &TP); Edge[T][i] = TP;//記錄邊 } Edge[0][i] = Price[i]; } } int dijkstra() { int i,j,k; for(i=1;i<=N;i++) { d[i]=Price[i];//初始化到每個點的距離 } for(i=1;i<=N;i++) { int tem=INF,u; for(j=1;j<=N;j++) { if(vis[j]==0&&d[j]<=tem) { u=j; tem=d[j]; } } vis[u]=1; for(k=1;k<=N;k++) { if(vis[k]==0&&d[u]+Edge[u][k]<d[k])//更新相鄰點 { d[k]=d[u]+Edge[u][k]; } } } return d[1]; } int main() { while(~scanf("%d %d", &M, &N)) { init(); read(); ans = INF; for(int i=1;i<=N;i++) { int minLevel = Level[i];//將目前的點視作等級最低的點 for(int j=1;j<=N;j++) { if(Level[j] - minLevel > M || minLevel > Level[j])vis[j] = 1;//如果有比它還低的點,或者差超過M,視為不合法 else vis[j] = 0; } int now = dijkstra(); ans = MIN(ans, now); } printf("%d\n", ans); } return 0; }