zoukankan      html  css  js  c++  java
  • poj2679 Adventurous Driving 最短路

     
    http://poj.org/problem?id=2679
    写完这道题内心是崩溃的, 写个题解纪念一下

    题意:

       给你n个点m条边,起点是st,终点是end,给你一些边,这些边带有费用和长度,让你求从起点到终点的最小费用,并且在满足最小费用时满足最小长度.

       输入(u,v,w1[len]w2) 表示u到v有一条费用为w1,长度为len的边;v到u有一条费用为w2,长度为len的有向边

    说下大概思路 

    1.先删边,保留与这个点相连最小的边

      具体实现:

        if(first[st] != -1&&val > a[first[st]].w)return;

        如果发现当前st所连接的上一条边的权值比当前插入边的权值小,就返回,不加入这条边

        if(first[st] != -1&&val < a[first[st]].w)first[st] = -1;

        那么反之,上一条边所连接的权值比当前插入的权值大,就把当期的first数组连向空节点,使得无法访问到权值的大边  

    2.spfa看起点能否到终点,不能到就输出VOID,能到 [并且无环] 直接输出最小费用和长度

    3.然后处理有负环的情况 , 判断从st到end的路上是否有环 , 如果直接spfa只能判断这个图上是否有环,而不是st到end的路上是否有环

      ①首先我们知道cnt数组[记录一个点入队次数,当入队次数大于n说明由负环]

      ②如果这个点的cnt大于n说明st可以到这个节点,并且这个点在一个环中

      ③对②中的点进行bfs[或者dfs]如果这个点能到end就说明这个点在环上并且end也在环上,那么就可以输出UNBOUND

      ④如果以上皆不符合就输出最小费用和长度

    PS:我就不用建反边的方法

      1 #include <stdio.h>
      2 #include <queue>
      3 #include <string.h>
      4 #define INF 100010
      5 #define maxn 50010
      6 #include <algorithm>
      7 using namespace std;
      8 int first[maxn], get[maxn], vis[maxn], cont[maxn], dis[maxn], le[maxn], flag;
      9 int n, m, st, end, tot, circle;
     10 struct node
     11 {
     12     int u, v, w, len, next;
     13 }a[maxn];
     14 void addedge(int st, int end, int val, int len)
     15 {
     16     if(first[st] != -1&&val > a[first[st]].w)return;
     17     if(first[st] != -1&&val < a[first[st]].w)first[st] = -1;
     18     a[++tot].u = st;a[tot].v=end;a[tot].w = val;a[tot].len = len;
     19     a[tot].next = first[st];first[st] = tot;
     20 }
     21 void bfs(int s)
     22 {
     23     queue<int > q;
     24     q.push(s);
     25     get[s] = 1;
     26     while(!q.empty())
     27     {
     28         int u = q.front();q.pop();
     29         for(int e = first[u]; e != -1; e = a[e].next)
     30         {
     31             int v = a[e].v;
     32             if(!get[v])
     33             {
     34                 get[v] = 1;
     35                 q.push(v);
     36             }
     37             if(v == end)
     38                 circle = 1;
     39         }
     40     }
     41 }
     42 int spfa()
     43 {
     44     queue<int > q;
     45     for(int i = 0; i <= n; i++)dis[i] = INF, vis[i] = 0;
     46     for(int i = 0; i <= n; i++)le[i] = INF;
     47     q.push(st);
     48     le[st] = 0;
     49     dis[st] = 0;
     50     vis[st] = 1;cont[st]++;
     51     while(!q.empty())
     52     {
     53         int u = q.front();q.pop();vis[u] = 0;
     54         for(int e = first[u]; e != -1; e = a[e].next)
     55         {
     56             int v = a[e].v;
     57             if(dis[u]+a[e].w < dis[v]||(dis[u]+a[e].w == dis[v]&&le[u]+a[e].len < le[v]))
     58             {
     59                 dis[v] = dis[u] + a[e].w;
     60                 le[v] = le[u] + a[e].len;
     61                 if(!vis[v])
     62                 {
     63                   q.push(v);
     64                   vis[v] = 1;
     65                   cont[v]++;
     66                  }
     67             }
     68             if(cont[v] > n+1)
     69             {
     70                 return 1;
     71             }
     72         }
     73     }
     74     return 0;
     75 }
     76 int main()
     77 {
     78     int x, y, w1, w2, len;
     79     while(~scanf("%d %d %d %d", &n, &m, &st, &end))
     80     {
     81         flag = 1;tot = 0;
     82         memset(first, -1, sizeof(first));
     83         memset(cont, 0, sizeof(cont));
     84         for(int i = 1; i <= m; i++)
     85         {
     86             scanf(" (%d,%d,%d[%d]%d)", &x, &y, &w1, &len, &w2);
     87             addedge(x, y, w1, len);addedge(y, x, w2, len);
     88         }
     89         flag = spfa();
     90         if(dis[end] == INF)
     91             printf("VOID
    ");
     92         else if(!flag){printf("%d %d
    ", dis[end], le[end]);continue;}
     93         else {
     94 
     95             for(int i = 0; i < n; i++)
     96             {
     97                 if(cont[i] > n){
     98                     memset(get, 0, sizeof(get));
     99                     circle = 0;
    100                     bfs(i);
    101                     if(circle)break;
    102                 }
    103             }
    104             if(circle || cont[end] > n)
    105                printf("UNBOUND
    ");
    106             else printf("%d %d
    ", dis[end], le[end]);
    107         }
    108     }
    109 }
    View Code
  • 相关阅读:
    Linux--shell的awk--10
    Spring Boot 整合 tk.mybatis
    pring Boot 整合 Druid
    Thymeleaf 模板布局
    Thymeleaf 内置对象
    Thymeleaf 表达式语法
    Thymeleaf 参考手册
    Thymeleaf常用语法
    Thymeleaf简介及第一个thymeleaf模板
    Docker 安装nginx
  • 原文地址:https://www.cnblogs.com/z52527/p/4776626.html
Copyright © 2011-2022 走看看