zoukankan      html  css  js  c++  java
  • JZOJ 4246. 【五校联考6day2】san

    题目

    Description

    小明经常去N 个地点,其中有些地点之间有直接的无向道路(共M 条这样的道路),可以直接互相到达,这些道路的长短不一。由于小明对这些道路都很熟悉,无论起点和终点在哪里,总能走最短路。小明有严重的强迫症,认为奇数很不和谐,如果他某一天从一个地点去另一个地点走过的路程是奇数,就会很不爽,但他又不想白白多走路,所以遇到最短路长度是奇数的情况就只能忍了。
    如果从某个地点A 到另一个地点B 的最短路径长度为奇数,则称这条最短路径为“不和谐最短路”。如果一条不和谐最短路上包含地点C,则称它为“经过C 的不和谐最短路”。现在请你编程求出对于每个地点,经过它的不同的不和谐最短路数量。两条最短路不同,当且仅当它们途径的地点的序列不同。
     

    Input

    第一行两个正整数N;M,含义见题面。
    接下来M 行,每行三个正整数Ai;Bi;Li,表示一条无向道路的两端和长度。

    Output

     N 行每行一个整数,第i 行表示经过第i 个点的不同的不和谐最短路条数。
     

    Sample Input

    4 4
    1 4 1
    1 2 1
    3 4 100
    2 3 2

    Sample Output

    6
    4
    2
    2
    样例说明
    长度为奇数的最短路有:1 → 2; 1 → 2 → 3; 1 → 4; 2 → 1; 3 → 2 → 1; 4 → 1。
    这些路径中四个点的经过次数分别为6, 4, 2, 2。
    其它一些路,如1 → 4 → 3 不是最短路,2 → 3 是最短路但长度为2,是偶数。这些路都不计入答案。
     

    Data Constraint

    对于50% 的数据,N ≤ 100;
    对于全部数据,N ≤ 1000;M ≤ 3000,每条路的长度不超过1000。
    保证图连通,无自环重边。

     

    分析

    • 一眼看去,我脑子里是满满的暴力
    • 可是我们如何暴力呢
    • 其实很显然,我们用每个节点作为起点
    • 跑几遍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 }
    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    __weak
    c++界面设计皮肤工具
    执行游戏时出现0xc000007b错误的解决方法
    2.4.1-Java语言基础(常量)
    句法模式识别(一)-串文法
    一步一步写算法(之hash表)
    LaTeX新人教程,30分钟从全然陌生到基本入门
    初次当面试官的经历和感触
    Android入门第八篇之GridView(九宫图)
    Android-Cannot merge new index 66195 into a non-jumbo instruction的解决的方法
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/10335595.html
Copyright © 2011-2022 走看看