【题意】
找出一个图中起始节点到目标节点代价最少并满足其他一些条件的路径
【思路】
类似的题在PAT里实在碰到太多遍了。。。依然是Dijkstra找最短路径长然后DFS找到所有最短路径并筛选的老套路
#include <iostream>
#include <map>
#include <vector>
#include <cstdio>
#include <string>
#include <stack>
using namespace std;
#define INF 0x0fffffff
map<string,int> name2id;
map<int,string> id2name;
vector<int> happiness,dist;
vector<vector<int>> weight;
stack<int> path;
int n,k,maxHappiness,cityCnt,pathCnt;
bool dfs(int index, int h, int cnt){
h += happiness[index];
cnt++;
if(index==name2id["ROM"]){
pathCnt++;
if(h>maxHappiness || (h==maxHappiness && cnt<cityCnt)){
maxHappiness = h;
cityCnt = cnt;
while(!path.empty()){
path.pop();
}
path.push(index);
return true;
}
return false;
}
else{
bool flag = false;
for(int i=0; i<n; i++){
if(dist[index]+weight[index][i]==dist[i]){
if(dfs(i,h,cnt)){
path.push(index);
flag = true;
}
}
}
return flag;
}
}
int main(int argc, char const *argv[])
{
cin >> n >> k;
happiness.resize(n);
dist.assign(n,INF);
weight.resize(n);
for(int i=0; i<n; i++){
weight[i].assign(n,INF);
}
vector<bool> visited;
visited.assign(n,0);
string name;
cin >> name;
name2id[name] = 0;
id2name[0] = name;
happiness[0] = 0;
for(int i=1; i<n; i++){
int h;
cin >> name >> h;
name2id[name] = i;
id2name[i] = name;
happiness[i] = h;
}
for(int i=0; i<k; i++){
string c[2];
int cost,id[2];
cin >> c[0] >> c[1] >> cost;
for(int j=0; j<2; j++){
id[j] = name2id[c[j]];
}
weight[id[0]][id[1]] = weight[id[1]][id[0]] = cost;
}
//Dijkstra
visited[0] = 1;
dist[0] = 0;
int index = 0;
for(int i=1; i<n; i++){
int min = INF, nextIndex;
for(int j=1; j<n; j++){
if(!visited[j]){
if(dist[index]+weight[index][j]<dist[j]){
dist[j] = dist[index]+weight[index][j];
}
if(dist[j]<min){
min = dist[j];
nextIndex = j;
}
}
}
if(min==INF){
break;
}
index = nextIndex;
visited[index] =1;
}
maxHappiness = -INF;
cityCnt = INF;
pathCnt = 0;
dfs(0,0,-1);
cout << pathCnt << " " << dist[name2id["ROM"]] << " " << maxHappiness << " " << maxHappiness/cityCnt << endl;
bool first = true;
while(!path.empty()){
if(first){
first = false;
}
else{
cout << "->";
}
cout << id2name[path.top()];
path.pop();
}
system("pause");
return 0;
}