最短路题目

负环 https://www.luogu.com.cn/problem/P3385

  • 使用BFS的SPFA算法和普通的SPFA没有什么区别,我们如何判断有没有负环呢?我们有两种判法.
  • 1.记录此点被更新了多少次,更新次数大于N就有负环.这意味着一个点被重复迭代超过N次,显然有负环.
  • 2.记录从S到当前点路径上经过了多少个点,超过N则有负环.这张图才有N个点,一条路径上没有重复点经过点数是<= N的,所以有负环.

用 t[ ] 表示被迭代多少次

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4
 5 #define M 6010
 6 #define N 2010
 7 #define clear(a) memset(a,0,sizeof(a))
 8
 9 using namespace std;
10
11 int dis[N],t[N];
12 bool vis[N];
13 int n,m,x,y,z,tot;
14 int hd[M];
15 struct node{
16     int ver,nxt,w;
17 }e[M];
18 queue<int> q;
19
20 void add(int x,int y,int z){
21     e[++tot].ver=y,e[tot].w=z,e[tot].nxt=hd[x],hd[x]=tot;
22 }
23
24 bool spfa(){
25     memset(dis,0x3f,sizeof(dis));
26     memset(vis,false,sizeof(vis));
27     memset(t,0,sizeof(t));
28     while(!q.empty()) q.pop();
29     dis[1]=0;vis[1]=1;t[1]=1;
30     q.push(1);
31     while(q.size()){
32         int x=q.front();q.pop();
33         vis[x]=0;
34         for(int i=hd[x];i;i=e[i].nxt){
35             int y=e[i].ver,z=e[i].w;
36             if(dis[y]>dis[x]+z){
37                 dis[y]=dis[x]+z;
38                 if(++t[y]>n) return 1;
39                 if(!vis[y]) q.push(y),vis[y]=1;
40             }
41         }
42     }
43     return 0;
44 }
45
46 int main()
47 {
48     int T;
49     cin>>T;
50     while(T--)
51     {
52         tot=0;memset(hd,0,sizeof(hd));
53         cin>>n>>m;
54         for(int i=1;i<=m;i++)
55         {
56             cin>>x>>y>>z;
57             if(z<0)  add(x,y,z);
58             else  add(x,y,z),add(y,x,z);
59         }
60         if(spfa())  cout<<"YE5"<<endl;//坑!!!
61         else  cout<<"N0"<<endl;
62     }
63     return 0;
64 }

原文地址:https://www.cnblogs.com/liukx/p/12375325.html

时间: 2024-10-18 04:10:04

最短路题目的相关文章

【POJ1062】昂贵的聘礼 最短路 题目描述还有数据都坑爹

题意:中文题,这里只提供题目传送门 http://poj.org/problem?id=1062 题解:首先若物品1可以由物品2加上x元得到,连一条B -> A的单向边,边权为x. 然后源点向每个物品连一条物品直接价格的边. 然后枚举点权的下限和上限. 好吧,很水.但是数据范围坑爹!!!点权还能是0!!而且酋长等级不一定最高!! 贴代码: #include <cstdio> #include <cstring> #include <algorithm> #defi

【最短路杂题】

最短路问题是图论中的经典问题,求解单源最短路问题可以采用dijkstra算法,时间复杂度O(n^2),使用堆优化后可以达到O(nlogn).在稀疏图中也可用spfa算法,并不比dijkstra算法表现的差.当然如果有负权值回路,dijkstra就只能GG了!求解全图中任意两点的最短路径还可以用floyd算法,时间复杂度O(n^3),虽然复杂度较高,但在需要的时候该算法也可表现的很好.求两点间的最短路径则可以通过深搜或广搜实现,时间复杂度O(m). 当然最短路问题可以有很多变形,比如下面几道题.

最短路总结

最近过的最短路题目稍微总结一下,顺便写一下模板,最短路算法众多有floyd.dij.bell-man.spfa,速度最快就是dij+优先队列或者dij+堆排序,spfa理论上很快o(ke)但实际并不一定不过spfa传说中有一个很NB用处就是处理带负权回路. 邻接表VS邻接矩阵:根据写题经验,如果可以用矩阵那一定是首选,矩阵速度比表快而且题目出现多重边时矩阵很好解决. 今天不小心又遇见正向表与最短路图(HDU2433),感觉很兴奋哈,通宵刷题的感觉很好玩!遗憾的是hdu1385还没过,那是一题最短

usaco题目分享——Bessie Come Home

Bessie Come HomeKolstad & Burch It's dinner time, and the cows are out in their separate pastures. Farmer John rings the bell so they will start walking to the barn. Your job is to figure out which one cow gets to the barn first (the supplied test da

poj1797 最短路

虽然不是求最短路,但是仍然是最短路题目,题意是要求1到N点的一条路径,由于每一段路都是双向的并且有承受能力,求一条路最小承受能力最大,其实就是之前POJ2253的翻版,一个求最大值最小,一个求最小值最大,于是只要修改最短路的更新条件就可以直接跑模板了 dij: 1 #include<stdio.h> 2 #include<string.h> 3 #include<vector> 4 #include<algorithm> 5 #include<queu

Codevs1041&amp;&amp;Vijos1119 car的旅行路线(最短路dijkstra)

Codevs1041&&Vijos1119  car的旅行路线(最短路) 题目描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t. 那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教.任务找出一条从城市A到B的旅游

Light oj 1099 - Not the Best 次短路

题目大意:求次短路. 题目思路:由于可能存在重边的情况所以不能采用邻接矩阵储存图,我用了邻接表来存图. 由起点S到终点E的次短路可能由以下情况组成: 1.S到v点的次短路 + v到E的距离 2.S到v的最短路 +  v到E的距离 对于每个节点,我们分别采用dist1[],dist2[]储存起点到该节点最短路与次短路 次短路的更新条件应是:对于点u,在本轮松弛操作中若 当前的dist1[u]可以被更新,我们用d2来储存还未被更新的dist1[u]. 若满足:dist2[u]>d2 &&

求最短路

求最短路 题目描述: 给定一张无向图,求一条经过边数最少的从点1到点N的最短路. 输入格式: 第一行两个整数N,M,表示点数和边数. 接下来M行每行三个整数,表示一条无向边的两端和它的边权.保证点的编号在[1, n]内. 输出格式: 一行两个整数,表示该最短路的长度,以及其经过的边数 如需输出64位整数,请使用cout或者printf("%I64d"). 样例输入: 3 3 1 2 1 2 3 1 1 3 2 样例输出: 2 1 提示: //虽然1->2->3也是最短路,但

最短路算法(floyed+Dijkstra+bellman-ford+SPFA)

最短路算法简单模板 一.floyed算法 首先对于floyed算法来说就是最短路径的动态规划解法,时间复杂度为O(n^3) 适用于图中所有点与点之间的最短路径的算法,一般适用于点n较小的情况. Floyed算法有三层循环,循环的层次先后顺序也是比较重要的,分别为k ,i,j:因为dis[k][i][j]代表的是i节点到j节点的最短路如果中间经过节点k的话dis[k][i][j] =dis[k-1][i][k]+dis[k-1][k][j]:否则dis[k][i][j] = dis[k-1][i]