JZOJ 4246. 【五校联考6day2】san
题目
分析
- 一眼看去,我脑子里是满满的暴力
- 可是我们如何暴力呢
- 其实很显然,我们用每个节点作为起点
- 跑几遍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 }
为何要逼自己长大,去闯不该闯的荒唐