题目
分析
- 一眼看去,我脑子里是满满的暴力
- 可是我们如何暴力呢
- 其实很显然,我们用每个节点作为起点
- 跑几遍spfa
- 用dfs来找到走过的路径,然后对应的点要++
- 但要注意的是,我们不能只找最小值去跟新
- 因为有可能不只是一条最短路径
代码
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<vector>
5 #include<queue>
6 using namespace std;
7 vector <int> f[1001];
8 queue <int> q;
9 int map[1001][1001];
10 int d[1001][1001],vis[1001],ans[1001];
11 int n,m,s;
12 int dfs(int x)
13 {
14 int sum=d[s][x]&1; ans[x]+=sum;
15 for (int i=0;i<f[x].size();i++)
16 {
17 int v=f[x][i],z;
18 if (d[s][x]+map[x][v]==d[s][v])
19 {
20 sum+=(z=dfs(v));
21 ans[x]+=z;
22 }
23 }
24 return sum;
25 }
26 void spfa(int i)
27 {
28 q.push(i);
29 memset(vis,0,sizeof(vis));
30 d[i][i]=0;
31 while(!q.empty())
32 {
33 int x;
34 x=q.front(); q.pop(); vis[x]=0;
35 for(int k=0;k<f[x].size(); k++)
36 {
37 int y=f[x][k];
38 if( d[i][x]+map[x][y]<d[i][y])
39 {
40 d[i][y]=d[i][x]+map[x][y];
41 if(!vis[y])
42 {
43 vis[y]=1;
44 q.push(y);
45 }
46 }
47 }
48 }
49 }
50
51 int main ()
52 {
53 cin>>n>>m;
54 for (int i=1,x,y,z;i<=m;i++)
55 {
56 cin>>x>>y>>z;
57 f[x].push_back(y);
58 f[y].push_back(x);
59 map[x][y]=z;
60 map[y][x]=z;
61 }
62 memset(d,0x3f,sizeof(d));
63 for (int i=1;i<=n;i++)
64 spfa(i);
65 for (s=1;s<=n;s++)
66 dfs(s);
67 for (int i=1;i<=n;i++)
68 cout<<ans[i]<<endl;
69 }