L2-036 网红点打卡攻略
起初是忽略了每个地点只能打卡一次的条件。
错误版本:
#include <bits/stdc++.h>
using namespace std;
int edges[210][210], fangan[2000][2000];
int minspend = INT_MAX;
int idx = 0;
int main() {
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c;
edges[a][b] = edges[b][a] = c;
}
int t;
cin >> t;
for (int i = 1; i <= t; i++) {//第i种方案
cin >> fangan[i][0];
for (int j = 1; j <= fangan[i][0]; j++) {
cin >> fangan[i][j];
}
}
int res = 0;//可行方案
for (int i = 1; i <= t; i++) {
int spend = 0;
if (fangan[i][0] != n) continue;
//检查方案
//是否能从家出发最后返回
if (edges[0][fangan[i][1]] == 0 || edges[0][fangan[i][6]] == 0) continue;
spend += edges[0][fangan[i][1]];
spend += edges[0][fangan[i][6]];
int j = 2;
for (j = 2; j <= 6; j++) {
if (edges[fangan[i][j]][fangan[i][j - 1]] == 0) {
break;//不可达
}
spend += edges[fangan[i][j]][fangan[i][j - 1]];
}
if (j > fangan[i][0]) {
res++;
if (spend < minspend) {
minspend = spend;
idx = i;
}
}
}
cout << res << '\n';
cout << idx << " " << minspend << '\n';
return 0;
}
正确版本:
#include <bits/stdc++.h>
using namespace std;
int edges[210][210], s[210],vis[210];//s当前路线 vis地点是否已经来过
int minspend = INT_MAX;
int idx = 0;
int main() {
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c;
edges[a][b] = edges[b][a] = c;
}
int count = 0;
int t;
cin >> t;
for (int i = 1; i <= t; i++) {//第i种方案
memset(vis, 0, sizeof(vis));
int cnt;
cin >> cnt;
for (int j = 1; j <= cnt; j++) {
cin >> s[j];
}
if (cnt != n) continue;
int spend = 0;//旅行线路的花销
int flag = 1;
int u = 0;//u是家的位置
for (int j = 1; j <= cnt; j++) {//检测i方案的可行性
//如果已经来过或者不可达
int v = s[j];
if (vis[v] || edges[u][v] == 0) {//也就是避免一个点
flag = 0;
break;
}
vis[v] = 1;//设置该地点已经访问过
spend += edges[u][v];
u = v;
}
//是否能够到家
if (edges[u][0] == 0) flag=0;
if (flag==0) {//如果方案不可行
continue;
}
count++;//方案可行 将方案数量增加
spend += edges[u][0];
if (spend < minspend) {//更新索引
minspend = spend;
idx = i;
}
}
cout << count << '\n';
cout << idx << " " << minspend << '\n';
return 0;
}