• POJ 3259 Wormholes


    http://poj.org/problem?id=3259

    这道题的意思就是 考虑从任意一个点出发 经过任意回路 (普通道路是双向 虫洞是单向并且是负边) 

    问回到出发点时 时间是不是小于 出发时的时间

    最开始直接想求所有点 到自己点的最短路 

    做着做着发现 如果可以的话 那不是没有最短路 因为每次都会更新---->>那不就是负圈

    --->>那不就是 判断是否存在负圈

    -->>所以直接用Bellman_ford的性质 判断负圈即可

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define INF 0x3f3f3f3f
     5 #define MAXV 507
     6 #define MAXE 5800
     7 using namespace std;
     8 
     9 struct Edge
    10 {
    11     int to, cost, next;//向前星 遍历边 然后松弛用向前星同样可以遍历边 只不过按起点而已
    12 }edge[MAXE];
    13 
    14 int head[MAXV];
    15 int num = 0;
    16 
    17 void Add(int from, int to, int c)
    18 {
    19     edge[num].cost = c;
    20     edge[num].to = to;
    21     edge[num].next = head[from];
    22     head[from] = num++;
    23 }
    24 
    25 int dist[MAXV];
    26 bool bellman_ford(int n)//顶点数
    27 {
    28     fill(dist, dist+n+3, 0);//全部变为0 查负圈
    29     for (int k = 0; k < n; k++)//不存在负圈 至多循环n-1次 按这个性质可以判断是否含有负圈
    30     for (int i = 1; i <= n; i++)
    31     {
    32         int t = head[i];
    33         while (t != -1)
    34         {
    35             Edge e = edge[t];
    36             if (dist[e.to] > dist[i] + e.cost)
    37             {
    38                 dist[e.to] = dist[i] + e.cost;
    39                 if (k == n-1) return true;//如果第n-1次仍然更新
    40             }
    41             t = e.next;
    42         }
    43     }
    44     return false;
    45 }
    46 int main()
    47 {
    48     int F;
    49     freopen("in.txt", "r", stdin);
    50     scanf("%d",&F);
    51     while(F--)
    52     {
    53         int N, M, W;
    54         num = 0;
    55         memset(edge, -1, sizeof(edge));
    56         memset(head, -1, sizeof(head));
    57         scanf("%d%d%d", &N, &M, &W);
    58         for (int i = 0;i < M; i++)
    59         {
    60             int from, to, cost;
    61             scanf("%d%d%d", &from, &to, &cost);
    62             Add(from, to, cost);
    63             Add(to, from, cost);//双向边
    64         }
    65         for (int i = 0; i < W; i++)
    66         {
    67             int from, to, cost;
    68             scanf("%d%d%d", &from, &to, &cost);
    69             Add(from, to, -cost);
    70         }
    71         if (bellman_ford(N)) cout << "YES" << endl;
    72         else cout << "NO" << endl;
    73     }
    74 }
  • 相关阅读:
    校内题目T2695 桶哥的问题——吃桶
    一位大佬对学习哲理的思考
    P2845 [USACO15DEC]Switching on the Lights 开关灯
    CF911F Tree Destruction
    CF995C Leaving the Bar
    CF997B Roman Digits
    P1667 数列
    P4035 [JSOI2008]球形空间产生器
    P2679 子串
    P2613 【模板】有理数取余
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/6399641.html
Copyright © 2020-2023  润新知