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\n");
 92         else if(!flag){printf("%d %d\n", 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\n");
106             else printf("%d %d\n", dis[end], le[end]);
107         }
108     }
109 }

时间: 2024-10-07 10:59:38

poj2679 Adventurous Driving 最短路的相关文章

POJ 2679:Adventurous Driving(SPFA+DFS)

http://poj.org/problem?id=2679 Adventurous Driving Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1596   Accepted: 455 Description After a period of intensive development of the transportation infrastructure, the government of Ruritania

POJ 2679 Adventurous Driving | SPFA + 判定负环

POJ 2679 Adventurous Driving 恶心的输入恶心的题面啊...这道题学到的东西还是蛮多的 Description..有向图..边权有两个:1.费用, 2.长度.要求找出S到T花费最小的路.一定要是花费最小....在花费最小的情况下输出路径长度的最小值..然后边权可以为负..不保证S到T一定有一条路..同时点a到点b之间可能有多条路... 总之就是..S不能到T输出VOID,S到T的路径上有负环(即没有最小值)输出UNBOUND..其他有解情况输出最小花费和最小路径长度..

ACM/ICPC 之 DFS+SPFA-贪心+最短路(POJ2679)

//POJ2679 //DFS+SPFA+邻接表 //只能走每个点费用最小的边,相同则需保证距离最短 //求最小费用及最短距离 //Time:47Ms Memory:900K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; #define MAXN 1105 #define

[ACM] HDU 4885 TIANKENG’s travel (特殊建图,最短路)

TIANKENG's travel Problem Description TIANKENG has get a driving license and one day he is so lucky to find a car. Every day he drives the car around the city. After a month TIANKENG finds that he has got high driving skills and he wants to drive hom

hdu 4885 TIANKENG’s travel (最短路+判断三点共线)

TIANKENG's travel Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 408    Accepted Submission(s): 100 Problem Description TIANKENG has get a driving license and one day he is so lucky to find a

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<

ACM/ICPC 之 昂贵的聘礼-最短路解法(POJ1062)

//转移为最短路问题,枚举必经每一个不小于酋长等级的人的最短路 //Time:16Ms Memory:208K #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAX 105 int lim, n; int p[M