社区讨论
大佬们帮帮萌新吧
P1841[JSOI2007] 重要的城市参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mjfocanu
- 此快照首次捕获于
- 2025/12/21 19:59 2 个月前
- 此快照最后确认于
- 2025/12/24 15:55 2 个月前
90ptsWA
思路是每个点的建造最短路图,然后对于u->v若v的入度为 则 为关键点。
我感觉思路大概没问题吧,如果思路没问题,我不会换成维护i到j的最短路径必经点的方法,因为正确性玄学,而且不用从1开始求最短路径条数又从n开始求最短路径条数乘法原理的方法做,比较弱智。
CPP#include <bits/stdc++.h>
using namespace std;
int n, m;
struct node {
int to, w;
} ;
vector <node> edge[205];
int dis[205][205], rd[205];
vector <int> e[205];
vector <int> mfY;
int vis[205];
inline void build (int x) {
// cout << x << '\n';
for (int i = 1; i <= n; i++) {
e[i].clear();
rd[i] = 0;
}
for (int i = 1; i <= n; i++) {
if (i == x) continue;
for (int j = 0; j < edge[i].size(); j++) {
int to = edge[i][j].to, w = edge[i][j].w;
if (dis[x][to] == dis[x][i] + w) {
e[i].push_back (to);
// cout << "\n" << i << " -> " << to << '\n';
rd[to]++;
}
}
}
for (int i = 1; i <= n; i++) {
if (i == x) continue;
for (int j = 0; j < e[i].size(); j++) {
int to = e[i][j];
if (rd[to] == 1) {
mfY.push_back (i);
}
}
}
}
int main () {
scanf ("%d%d", &n, &m);
memset (dis, 0x3f, sizeof (dis));
for (int i = 1; i <= n; i++) dis[i][i] = 0;
for (int i = 1; i <= m; i++) {
int x, y, w;
scanf ("%d%d%d", &x, &y, &w);
dis[x][y] = w;
dis[y][x] = w;
edge[x].push_back ({y, w});
edge[y].push_back ({x, w});
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (dis[i][k] != 0x3f3f3f3f && dis[k][j] != 0x3f3f3f3f && dis[i][k] + dis[k][j] < dis[i][j]) {
dis[i][j] = dis[i][k] + dis[k][j];
}
}
}
}
int flag = 0;
for (int dot = 1; dot <= n; dot++) {
mfY.clear();
build (dot);
// cout<<dot<<":"<<endl;
for (int i = 0; i < mfY.size(); i++) {
flag = 1;
// cout << mfY[i] << ' ';
vis[mfY[i]] = 1;
}
// cout <<endl;
}
for (int i = 1; i <= n; i++) {
if (vis[i]) {
printf ("%d ", i);
}
}
if (flag == 0) {
printf ("No important cities.");
}
return 0;
}
谢谢大佬帮我调题,玄关一个。
回复
共 2 条回复,欢迎继续交流。
正在加载回复...