考察:无向有权图的最短路径;
解决办法:1、节点少情况:直接DFS从呼救点去遍历全图,终结点只进入还有救护车的医院,过程中更新最短路径,救护车数量,经过节点数。
2、节点多情况:采用Dijkstra+DFS,用Dij记录每个医院到每个呼救点的最短路径,pre保存,然后用DFS遍历更新找到对应path.
注意点:途中可以经过医院,节点数大于1000,用dij+DFS;
办法一DFS:
using namespace std;
const int maxn = 1011;
const int INF = 1000000;
int G[maxn][maxn]={0};
int na,ns,m,k;
int mindis=INF,mincount = INF,maxcar = -1;
vector<int> tempPath,path,avinum;
bool vis[maxn] = {false};
void DFS(int quy) {
vis[quy] = true;
if(quy > ns && avinum[quy-ns] > 0) {
tempPath.push_back(quy);
int sumdis = 0;
for(int i=0; i< tempPath.size()-1; i++) {
sumdis += G[tempPath[i]][tempPath[i+1]];
}
if(mindis > sumdis) {
path = tempPath;
mindis = sumdis;
maxcar = avinum[quy-ns];
mincount = tempPath.size();
}else if(mindis==sumdis && maxcar < avinum[quy-ns]){
maxcar = avinum[quy-ns];
mincount = tempPath.size();
path = tempPath;
}else if(mindis==sumdis && maxcar == avinum[quy-ns] && tempPath.size() < mincount) {
mincount = tempPath.size();
path = tempPath;
}
tempPath.pop_back();
}
tempPath.push_back(quy);
for(int i=0; i< maxn; i++) {
if(vis[i] == false && G[quy][i]!=0) {
vis[i]=true;
DFS(i);
vis[i]=false;
}
}
vis[quy] = false;
tempPath.pop_back();
}
int main() {
cin>>ns>>na;
avinum.resize(na+1);
for(int i=1; i <= na; i++) cin >> avinum[i];
cin>>m;
string v1,v2,str;
int time,quy;
for(int i=0; i<m; i++) {
cin>>v1>>v2>>time;
int n1 = v1[0]=='A'?stoi(v1.substr(2))+ns:stoi(v1);
int n2 = v2[0]=='A'?stoi(v2.substr(2))+ns:stoi(v2);
G[n1][n2] = G[n2][n1] = time;
}
cin>>k;
for(int i=0; i<k; i++) {
path.clear();
tempPath.clear();
maxcar = -1;
mincount = mindis = INF;
cin>>quy;
DFS(quy);
if(path.size() == 0) cout <<"All Busy"<<endl;
else {
avinum[path[path.size()-1]-ns]--;
for(int j = path.size()-1; j>=0; j--) {
str = path[j]>ns? ("A-"+ to_string(path[j]-ns)):to_string(path[j]);
cout<<str;
if(j!=0) cout<<" ";
}
cout<<endl<<mindis<<endl;
}
}
return 0;
}
方法二(dijkstra+DFS):参考20-浙大计算机考研总群241321218 20-云同学代码
#include<bits/stdc++.h>
using namespace std;
const int INF=1000000000;
int weight[15],G[1015][1015],d[15][1015];
vector<int> pre[15][1015],temp,path;
bool inq[1015];
int ns,na,m,k;
void dijkstra(int index){
fill(inq,inq+1015,false);
fill(d[index],d[index]+1015,INF);
d[index][1000+index]=0;
for(int i=1;i<=1000+na;i++){
int u=-1,MIN=INF;
for(int j=1;j<=1000+na;j++){
if(inq[j]==false&&d[index][j]<MIN){
MIN=d[index][j];
u=j;
}
}
if(u==-1) return;
inq[u]=true;
for(int v=1;v<=1000+na;v++){
if(inq[v]==false&&G[u][v]!=INF){
if(d[index][u]+G[u][v]<d[index][v]){
pre[index][v].clear();
pre[index][v].push_back(u);
d[index][v]=d[index][u]+G[u][v];
}else if(d[index][u]+G[u][v]==d[index][v]) pre[index][v].push_back(u);
}
}
}
}
void dfs(int s,int ed){
temp.push_back(s);
if(s==ed+1000){
if(path.size()==0) path=temp;
else {
if(temp.size()<=path.size()) path=temp;
}
temp.pop_back();
return;
}
for(int i=0;i<pre[ed][s].size();i++){
dfs(pre[ed][s][i],ed);
}
temp.pop_back();
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("test.txt","r",stdin);
#endif
scanf("%d%d",&ns,&na);
for(int i=1;i<=na;i++) scanf("%d",&weight[i]);
scanf("%d",&m);
fill(G[0],G[0]+1015*1015,INF);
for(int i=0;i<m;i++){
char str[10];
int u,v;
scanf("%s",str);
if(str[0]=='A'){
sscanf(str,"A-%d",&u);
u+=1000;
}else u=stoi(str);
scanf("%s",str);
if(str[0]=='A'){
sscanf(str,"A-%d",&v);
v+=1000;
}else v=stoi(str);
scanf("%d",&G[u][v]);
G[v][u]=G[u][v];
}
for(int i=1;i<=na;i++){
dijkstra(i);
}
scanf("%d",&k);
for(int i=0;i<k;i++){
int aim,mindis=INF,maxleft=-1,index;
vector<int> res;
scanf("%d",&aim);
for(int j=1;j<=na;j++){
if(weight[j]>0){
if(d[j][aim]<mindis){
mindis=d[j][aim];
maxleft=weight[j];
dfs(aim,j);
res=path;
path.clear();
index=j;
}else if(d[j][aim]==mindis&&weight[j]>weight[index]){
dfs(aim,j);
maxleft=weight[j];
res=path;
path.clear();
index=j;
}else if(d[j][aim]==mindis&&weight[j]==weight[index]){
dfs(aim,j);
if(path.size()<res.size()) res=path,index=j;
path.clear();
}
}
}
if(maxleft==-1) printf("All Busy\n");
else {
weight[index]--;
for(int j=res.size()-1;j>=0;j--){
if(res[j]>1000) printf("A-%d",res[j]-1000);
else printf("%d",res[j]);
if(j) printf(" ");
else printf("\n");
}
printf("%d\n",d[index][aim]);
}
}
}