• Gym 100917F Find the Length


    题目链接:http://codeforces.com/gym/100917/problem/F

    ------------------------------------------------------------------------------------------------

    给出一个无向正权无自环图 要求对于每个点 经过它的最短"简单环"的长度

    其中简单环的定义是 环上每条无向边都经过且仅经过一次

    显然这个环至少经过三条边 三个点

    我们或许会产生这样一种思路 对于每次询问 我们以该点$s$作为起点

    先处理出到其余每点的最短路 然后枚举一条边  两端分别为$u v$

    用$s$分别到$u v$的最短路再加上这条边的长度来更新结果

    然而这样连样例都过不了 因为会产生重边

    于是我们考虑把最短路径所经过的边都标记一下(多个可选的话随便标记一个)

    然后枚举边的时候碰到标记过的边就直接跳过

    不过这样还存在一种情况 就是 $u v$ 属于最短路径边所构成树上的除根节点外同一子树

    这种情况也是会有重边的 所以这里再判断以下去除就好

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <algorithm>
     5 using namespace std;
     6 const int N = 310, E = N * N * 2;
     7 int firste[N], nexte[E], v[E], w[E], flag[E];
     8 int used[N], dist[N], fa[N];
     9 int n, e = 1;
    10 void build(int x, int y, int z)
    11 {
    12     nexte[++e] = firste[x];
    13     firste[x] = e;
    14     v[e] = y;
    15     w[e] = z;
    16 }
    17 int main()
    18 {
    19     scanf("%d", &n);
    20     int x;
    21     for(int i = 1; i <= n; ++i)
    22         for(int j = 1; j <= n; ++j)
    23         {
    24             scanf("%d", &x);
    25             if(i >= j)
    26                 continue;
    27             if(x != -1)
    28             {
    29                 build(i, j, x);
    30                 build(j, i, x);
    31             }
    32         }
    33     for(int i = 1; i <= n; ++i)
    34     {
    35         int u = i;
    36         for(int j = 1; j <= n; ++j)
    37             fa[j] = j;
    38         memset(dist, 0x3f, sizeof dist);
    39         dist[u] = 0;
    40         for(int t = 1; t < n; ++t)
    41         {
    42             used[u] = i;
    43             int mdist = 1e9, tu;
    44             for(int p = firste[u]; p; p = nexte[p])
    45                 if(dist[v[p]] > dist[u] + w[p])
    46                     dist[v[p]] = dist[u] + w[p];
    47             for(int j = 1; j <= n; ++j)
    48                 if(used[j] != i && dist[j] < mdist)
    49                 {
    50                     tu = j;
    51                     mdist = dist[j];
    52                 }
    53             for(int p = firste[tu]; p; p = nexte[p])
    54                 if(dist[tu] == dist[v[p]] + w[p])
    55                 {
    56                     flag[p] = flag[p ^ 1] = i;
    57                     if(v[p] != i)
    58                         fa[tu] = fa[v[p]];
    59                     break;
    60                 }
    61             u = tu;
    62         }
    63         int ans = 1e9;
    64         for(int p = 2; p < e; p +=2)
    65             if(flag[p] != i && fa[v[p]] != fa[v[p ^ 1]])
    66                 ans = min(ans, dist[v[p]] + dist[v[p ^ 1]] + w[p]);
    67         printf("%d
    ", ans < 1e9 ? ans : -1);
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    福大软工 · 第八次作业(课堂实战)- 项目UML设计(团队)
    福大软工1816 · 第六次作业
    2018软工实践——团队答辩
    福大软工1816 · 第五次作业
    福大软工1816 · 第二次作业
    福大软工1816 · 第一次作业
    个人作业——软件产品案例分析
    第二次结对编程作业--毕设导师智能匹配
    结对项目之需求分析与原型设计
    调研《构建之法》指导下的全国高校的历届软工实践作品、全国互联网+竞赛、物联网竞赛等各类全国性大学生信息化相关的竞赛平台的历届作品
  • 原文地址:https://www.cnblogs.com/sagitta/p/5324969.html
Copyright © 2020-2023  润新知