题意:图中有C个点,R条边,每个点有个权值,每条边也有距离值,求A到B点的最短距离+经过的点的最大值的和最小
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cstdlib> #include<string> #include<queue> #include<vector> #include<set> #include<stack> #include<climits> using namespace std; vector<int> e[105],w[105]; int n,m,q,cost[105],dist[105],dp[105][105]; bool vis[105]; void spfa(int u) { queue<int> q; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) dist[i]=INT_MAX; dist[u]=0; vis[u]=1; q.push(u); while(!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for(int i=0;i<e[x].size();i++) { int v=e[x][i]; int ww=w[x][i]; if(dist[v]>dist[x]+ww&&cost[v]<=cost[u]) { dist[v]=dist[x]+ww; if(!vis[v]) { vis[v]=1; q.push(v); } } } } for(int i=1;i<=n;i++) dp[u][i]=dist[i]; } int main() { int cas=1; while(scanf("%d%d%d",&n,&m,&q)!=EOF) { if(n+m+q==0) break; for(int i=1;i<=n;i++) e[i].clear(),w[i].clear(); for(int i=1;i<=n;i++) scanf("%d",&cost[i]); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) dp[i][j]=INT_MAX; } for(int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); e[x].push_back(y); e[y].push_back(x); w[x].push_back(z); w[y].push_back(z); } for(int i=1;i<=n;i++) spfa(i); int ans; if(cas) printf("\n"); printf("Case #%d\n",++cas); while(q--) { int x,y; ans=INT_MAX; scanf("%d%d",&x,&y); for(int i=1;i<=n;i++) { if(dp[i][x]>=INT_MAX||dp[i][y]>=INT_MAX) continue; ans=min(ans,dp[i][x]+dp[i][y]+cost[i]); } if(ans>=INT_MAX) printf("-1\n"); else printf("%d\n",ans); } } return 0; }
时间: 2024-11-09 07:30:20