原题链接:http://www.patest.cn/contests/pat-a-practise/1003
典型的最短路径,也稍微变了下。
Dijkstra算法,麻烦,容易出错。
#include <iostream>
#include <fstream>
#include <algorithm>
#define INT_MAX 2147483647
#define INT_MIN (-2147483647 - 1)
using namespace std;
int path[500][500];
int d[500];
int exist[500];
int s, e;
int n, m;
int rescue[500];
int cnt[500];
int r[500];
void in()
{
ifstream cin("in.txt");
cin >> n >> m >> s >> e;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
path[i][j] = INT_MAX;
}
}
for (int i = 0; i < n; i++)
{
cin >> rescue[i];
}
for (int i = 0; i < m; i++)
{
int a, b;
cin >> a >> b;
cin >> path[a][b];
path[b][a] = path[a][b];
}
}
int nearest()
{
int max = INT_MAX;
int index;
for (int i = 0; i < n; i++)
{
if (!exist[i] && d[i] < max)
{
max = d[i];
index = i;
}
}
return index;
}
void shortest()
{
exist[s] = 1;
for (int i = 0; i < n; i++)
{
d[i] = path[s][i];
cnt[i] = (d[i] == INT_MAX) ? 0 : 1;
r[i] = (d[i] == INT_MAX) ? INT_MIN : rescue[i] + rescue[s];
}
r[s] = rescue[s];
d[s] = 0;
cnt[s] = 1;
for (int i = 0; i < n - 1; i++)
{
int index = nearest();
exist[index] = 1;
for (int j = 0; j < n; j++)
{
if (exist[j] || path[index][j] == INT_MAX)
{
continue;
}
if (d[index] + path[index][j] < d[j])
{
d[j] = d[index] + path[index][j];
cnt[j] = cnt[index];
r[j] = r[index] + rescue[j];
}
else if (d[index] + path[index][j] == d[j])
{
cnt[j] += cnt[index];
r[j] = max(r[index] + rescue[j], r[j]);
}
}
}
cout << cnt[e] << ' ' << r[e] << endl;
}
int main(int argc, char **argv)
{
in();
shortest();
return 0;
}
dfs深搜,最好的算法,简洁,复杂度高。
#include <iostream>
#include <fstream>
int d[500][500];
int visited[500];
int teams[500];
int n, m;
int s, e;
#define INF 0x7fffffff
int min_dist=INF;
int max_amount;
int cnt;
using namespace std;
void dfs(int start, int dist, int amount)
{
//下面的continue是剪枝
if (start == e)
{
if (dist < min_dist)
{
cnt = 1;
min_dist = dist;
max_amount = amount;
}
else if (dist == min_dist)
{
cnt++;
if (amount>max_amount)
{
max_amount = amount;
}
}
return;
}
for (int i = 0; i < n; i++)
{
if (d[start][i] != 0 && !visited[i])
{
visited[i] = 1;
dfs(i, dist+d[start][i], amount+teams[i]);
visited[i] = 0;
}
}
}
int main(int argc, char **argv)
{
ifstream cin("in.txt");
cin >> n >> m >> s >> e;
for (int i = 0; i < n; i++)
{
cin >> teams[i];
}
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
d[a][b] = d[b][a] = c;
}
visited[s] = 1;
dfs(s, 0, teams[s]);
cout << cnt << ' ' << max_amount << endl;
return 0;
}
bfs广搜,还行。不算麻烦。
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#define INF 0x7fffffff
using namespace std;
int teams[500];
int dist[500][500];
int n, m;
int s, e;
vector<vector<int> > ve;
int d[500];
int cnt = 0;
int max_amount = 0;
int min_dist = INF;
void bfs(int s, int e)
{
vector<int> data;
data.push_back(s);
data.push_back(0);
data.push_back(teams[s]);
ve.push_back(data);
int i = 0;
while (i<ve.size())
{
data = ve[i++];
int start, pathdist, amount;
start = data[0];
pathdist = data[1];
amount = data[2];
//下面两处continue是剪枝
if (start == e)
{
if (pathdist < min_dist)
{
min_dist = pathdist;
max_amount = amount;
cnt = 1;
}
else if (pathdist == min_dist)
{
cnt++;
if (amount>max_amount)
{
max_amount = amount;
}
}
continue;
}
else if (d[start] > 0 && pathdist > d[start])
{
continue;
}
d[start] = pathdist;
for (int i = 0; i < n; i++)
{
if (dist[start][i] != 0)
{
data.clear();
data.push_back(i);
data.push_back(d[start] + dist[start][i]);
data.push_back(amount + teams[i]);
ve.push_back(data);
}
}
}
cout << cnt << ' ' << max_amount << endl;
}
int main(int argc, char **argv)
{
ifstream cin("in.txt");
cin >> n >> m >> s >> e;
for (int i = 0; i < n; i++)
{
cin >> teams[i];
}
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
dist[a][b] = dist[b][a] = c;
}
bfs(s, e);
return 0;
}