题目大意:
小明经常去N 个地点,其中有些地点之间有直接的无向道路(共M 条这样的道路),可以直接互相到达,这些道路的长短不一。由于小明对这些道路都很熟悉,无论起点和终点在哪里,总能走最短路。小明有严重的强迫症,认为奇数很不和谐,如果他某一天从一个地点去另一个地点走过的路程是奇数,就会很不爽,但他又不想白白多走路,所以遇到最短路长度是奇数的情况就只能忍了。
如果从某个地点A 到另一个地点B 的最短路径长度为奇数,则称这条最短路径为“不和谐最短路”。如果一条不和谐最短路上包含地点C,则称它为“经过C 的不和谐最短路”。现在请你编程求出对于每个地点,经过它的不同的不和谐最短路数量。两条最短路不同,当且仅当它们途径的地点的序列不同。
解题思路:
跑一遍
S
P
F
A
SPFA
SPFA我才不会告诉你我用dij+堆优化T了
然后暴搜最短路上的边,加一些剪枝就能过
A c c e p t e d c o d e : Accepted\ code: Accepted code:
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const long long inf = 1e9;
const int N = 1005;
const int M = 3005;
struct Line {
int to, next;
long long w;
}e[M<<1];
queue <int> q;
//priority_queue < pair<int, int> > q;
int n, m, cnt;
int b[N], f[N], vis[N], num[N], dis[N], last[N];
inline void addline(int x, int y, int z) {
e[++cnt] = (Line){y, last[x], z}; last[x] = cnt;
}
/*void dij(int S) {
for (int i = 1; i <= n; ++i)
dis[i] = inf, vis[i] = 0;
dis[S] = 0;
while (q.size()) q.pop();
q.push(make_pair(0, S));
while (q.size()) {
int x = q.top().second; q.pop();
if (vis[x]) continue;
vis[x] = 1;
for (int i = last[x], y; ~i; i = e[i].next) {
y = e[i].to;
if (dis[y] > dis[x] + e[i].w) {
dis[y] = dis[x] + e[i].w;
if (!vis[y])
q.push(make_pair(-dis[y], y));
}
}
}
}*/
void Spfa(int S) {
for (int i = 1; i <= n; ++i)
dis[i] = inf, vis[i] = 0;
dis[S] = 0; vis[S] = 1;
while (q.size()) q.pop();
q.push(S);
while (q.size()) {
int x = q.front(); q.pop(); vis[x] = 0;
for (int i = last[x], y; ~i; i = e[i].next) {
y = e[i].to;
if (dis[y] > dis[x] + e[i].w) {
dis[y] = dis[x] + e[i].w;
if (!vis[y])
q.push(y),
vis[y] = 1;
}
}
}
}
void dfs(int now, int fa) {
f[now] = dis[now] & 1;
for (int i = last[now]; ~i; i = e[i].next)
if (e[i].to != fa && dis[e[i].to] == dis[now] + e[i].w)
dfs(e[i].to, now), f[now] += f[e[i].to];
num[now] += f[now];
}
int main() {
memset(last, -1, sizeof last);
scanf("%d %d", &n, &m);
for (int i = 1, x = 0, y = 0, z = 0; i <= m; ++i)
scanf("%d %d %d", &x, &y, &z),
addline(x, y, z), addline(y, x, z);
for (int i = 1; i <= n; ++i) {
Spfa(i);
dfs(i, 0);
}
for (int i = 1; i <= n; ++i)
printf("%d\n", num[i]);
}