图论刷水题记录(二)(最短路-----SPFA算法)
继第一篇的后续,又来刷水题了,写的是SPFA算法,这个算法的复杂度比较玄学,感觉能不用就不用了,但是他的好处就是可以判断负圈。
3月26日:
1.POJ 1847 Tram
题意:在一个交通网络上有N个路口, 每个路口指向多个方向, 默认驶向第一个方向, 驶向其他方向时需要进行一次操作, 求从a到b最小的操作数
直接建图即可,默认的方向权值为0,其他方向权值为1。
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn 110
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
int n,st,en;
int visited[maxn];
struct wazxy{int v,next,w;
}edge[maxn*maxn];
int head[maxn];
int dis[maxn];
int cnt=0;
void init(){memset(visited,false,sizeof(visited));memset(dis,MaxN,sizeof(dis));memset(head,-1,sizeof(head));
}
void add(int u,int v,int w){edge[cnt].w=w;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;
}
void spfa(){queue<int> q;q.push(st);dis[st]=0;while(!q.empty()){int temp=q.front();q.pop();visited[temp]=false;for(int i=head[temp];~i;i=edge[i].next){int v=edge[i].v;int w=dis[temp]+edge[i].w;if(dis[v]>w){dis[v]=w;if(!visited[v]){visited[v]=true;q.push(v);}}}}
}
int main()
{cin>>n>>st>>en;init();for(int i=1;i<=n;i++){int m,x;scanf("%d",&m);bool flag=true;for(int f=1;f<=m;f++){scanf("%d",&x);if(flag) add(i,x,0),flag=false;else add(i,x,1);// cout<<i<<" "<<x<<endl;}}spfa();// for(int i=1;i<=n;i++) cout<<dis[i]<<endl;if(dis[en]!=MaxN) printf("%d\n",dis[en]);else printf("-1\n");return 0;
}
2.POJ 2502 Subway
首先,原谅我这个题做了一晚上,找了一个多小时的bug,当ac此题时,原谅我仰天长啸3s,出错原因竟然是极大值附小了,我他妈!!!!!!淦
题意:个人要从家到学校,步行速度10km/h,图上有地铁40km/h,地铁有不同线路,每个线路上的地铁可以互通,相邻两站之间地铁以直线运行,不同地铁线路之间不能直接通过地铁乘坐到达,但不同地点间可以直接步行,按直线走。给出家、学校、各地铁站台的坐标(单位 m),问从家到学校最短需要花费多少时间(min),不要忘记换算单位。
思路:先把每条铁路建成图(速度为车速),再把每个站点之间连起来(相当于人走)。
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn 100010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
int sx,sy,ex,ey;
int n;
bool visited[maxn];
struct wazxy{int v,next;double w;
}edge[maxn];
struct point{int x,y;
}a[maxn];
int head[maxn];
long double dis[maxn];
int cnt=0;
int num=1;
void init(){memset(visited,false,sizeof(visited));for(int i=0;i<maxn;i++) dis[i]=1e18;memset(head,-1,sizeof(head));
}
void add(int u,int v,double w){edge[cnt].w=w;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;
}
void spfa(){queue<int> q;q.push(0);dis[0]=0;while(!q.empty()){int temp=q.front();q.pop();visited[temp]=false;for(int i=head[temp];~i;i=edge[i].next){int v=edge[i].v;double w=dis[temp]+edge[i].w;if(dis[v]>w){dis[v]=w;if(!visited[v]){visited[v]=true;q.push(v);}}}}
}
inline double getlen(double x,double y,double x1,double y1,double s){return 60*sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1))/s/1000;
}
int main()
{cin>>sx>>sy>>ex>>ey;int x,y,x1,y1;a[0].x=sx,a[0].y=sy;init();while(scanf("%d%d",&x,&y)!=EOF){a[num].x=x,a[num++].y=y;while(scanf("%d%d",&x1,&y1)!=EOF&&x1!=-1){a[num].x=x1,a[num++].y=y1;double temp=getlen(x,y,x1,y1,40);// cout<<temp<<endl;add(num-2,num-1,temp);add(num-1,num-2,temp);x=x1,y=y1;}}a[num].x=ex,a[num++].y=ey;for(int i=0;i<num;i++){for(int j=0;j<num;j++){if(i==j) continue;double temp=getlen(a[i].x,a[i].y,a[j].x,a[j].y,10);// cout<<temp<<endl;add(i,j,temp);}}num--;spfa();//for(int i=0;i<=num;i++) cout<<dis[i]<<endl;printf("%d\n",(int)(dis[num]+0.5));return 0;}
3.POJ 1062 昂贵的聘礼
这个题只需要额外的一个附加条件,就是在某段区间内进行查询最短,在spfa种设置一个范围即可。
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn 1010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
ll mod = 998244353;
using namespace std;
struct wazxy{int v,w,next;
}edge[100010];
bool visited[maxn];
int dis[maxn];
int lv[maxn];
int cnt=0;
int head[maxn];
int n,m;
void add(int u,int v,int w){edge[cnt].v=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;
}
int spfa(int l,int r){memset(visited,false,sizeof(visited));memset(dis,MaxN,sizeof(dis));queue<int> q;dis[0]=0;q.push(0);while(!q.empty()){int temp=q.front();q.pop();visited[temp]=false;for(int i=head[temp];~i;i=edge[i].next){int v=edge[i].v;if(!(lv[v]>=l&&lv[v]<=r)) continue;int w=dis[temp]+edge[i].w;if(dis[v]>w){dis[v]=w;if(!visited[v]){visited[v]=false;q.push(v);}}}}return dis[1];
}
int main()
{memset(head,-1,sizeof(head));cin>>m>>n;for(int i=1;i<=n;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);add(0,i,x);lv[i]=y;while(z--){int v,w;scanf("%d%d",&v,&w);add(v,i,w);}}int imin=MaxN;for(int i=lv[1]-m;i<=lv[1];i++){imin=min(imin,spfa(i,i+m));}cout<<imin<<endl;return 0;
}
3月30
4.poj1860 Currency Exchange floyd
出去爬了个泰山,还是比较累的,继续鏖战最短路
思路:这个题目利用了spfa判断正环,这个做法是最保险的,因为如果存在正环的话金钱就会一直增加。
代码:
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn 1010
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
ll mod = 998244353;
using namespace std;
int visited[maxn];
double dis[maxn];
int n,m,s;
double v;
int head[maxn];
struct wazxy{double w;int next;double rate;int v;
}edge[1010];
int cnt=0;
int ans[maxn];
void add(int u,int v,double r,double w){edge[cnt].rate=r;edge[cnt].v=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;
}
bool spfa(){queue<int> q;q.push(s);visited[s]=true;dis[s]=v;ans[s]++;while(!q.empty()){int temp=q.front();q.pop();visited[temp]=false;for(int i=head[temp];~i;i=edge[i].next){int to=edge[i].v;double r=edge[i].rate;double w=edge[i].w;if(dis[to]<(dis[temp]-w)*r){dis[to]=(dis[temp]-w)*r;if(!visited[to]){visited[to]=true;ans[to]++;q.push(to);}if(ans[to]>n) return true;}}}return false;
}
int main()
{cin>>n>>m>>s>>v;memset(visited,false,sizeof(visited));memset(head,-1,sizeof(head));for(int i=0;i<maxn;i++) dis[i]=0;for(int i=1;i<=m;i++){int x,y;double a,b;cin>>x>>y>>a>>b;add(x,y,a,b);cin>>a>>b;add(y,x,a,b);}if(spfa()) cout<<"YES"<<endl;else cout<<"NO"<<endl;return 0;
}
昨晚本来想写,遗憾的是女朋友被猫咬了,陪她去医院打针没写成;;
算了就写这些吧
图论刷水题记录(二)(最短路-----SPFA算法)相关推荐
- 图论刷水题记录(一)(最短路-----dijkstra算法)
最近实在不知道干些什么,感觉自己除了水题什么都不会做,算了去刷一刷图论的水题吧本来想合起来一起发,想了想太长的话以后看起来也不方便,题目所以今天晚上就先发了dij部分,由上到下由易变难. 1.POJ ...
- 每日刷题记录 (二十)
文章目录 第一题: 16. 最接近的三数之和 解题思路: 代码实现: 第二题: 43. 字符串相乘 解题思路: 代码实现: 第三题: 59. 螺旋矩阵 II 解题思路: 代码实现: 第四题: 89. ...
- 闲来无事刷水题、简单博弈论专题、sg函数、洛谷
记 今天闲来无事,不想刷codeforces了,到洛谷提高组训练营找几道水题刷着玩玩(虽然自己早已过了打OI的年纪)- 简单博弈论专题 P1199 三国游戏 这么考虑,由于电脑总是不能让我搭配出当前能 ...
- buu 水题记录(一)
buuctf crypto Before Crypto MD5 Url编码 看我回旋踢 一眼就解密 摩丝 变异凯撒 Quoted-printable Rabbit RSA 篱笆墙的影子 丢失的MD5 ...
- 单源最短路 SPFA 算法模板
简介 在图论中,最短路是十分重要的一部分,在很多问题中都有涉及 而现在所讲的 SPFA 算法是十分优秀的算法,时间复杂度为 O(k∗E)O(k*E) 其中 EE 是图的边数,而 kk 是一个常数,一般 ...
- 每日刷题记录 (二十七)
文章目录 第一题: 1108. IP 地址无效化 解题思路: 代码实现: 第二题: 1431. 拥有最多糖果的孩子 解题思路: 代码实现: 第三题: 1720. 解码异或后的数组 解题思路: 代码实现 ...
- Cryptohack刷题记录(二) Mathematics部分 Modular Math WriteUp
文章目录 MATHEMETICS MODULAR MATH 1. Quadratic Residues 2. Legendre Symbol 3. Modular Square Root 4. Chi ...
- LeetCode —— 深搜水题记录
正文之前 好长一段时间没有更新博客了,是因为放假了都是一整个白天地去学车,然后晚上看看书,做一做题就过去了,好在已经完成驾照考试,但是最近又没有研究什么技术,所以就只好拿这几天做的 LeetCode ...
- 堆排序时间复杂度_leetcode刷题(二):排序算法(归并排序,堆排序,桶排序)...
今天,我们要来讲讲排序问题,这次讲的排序算法主要是归并排序,堆排序和桶排序. 归并排序 归并一词在中文的含义就是"合并,并入"的意思,在数据结构里面就是将两个或者两个以上的有序数组 ...
最新文章
- Java方法详细介绍
- mysql汉化版不同_Mysql各个版本区别及官网下载
- 经典mysql数据库表案例_MySQL数据库的“十宗罪”(附10大经典错误案例)
- mysql 社区版 阿里云_Mysql各版本介绍及下载
- 异步接口同步返回_同步|异步
- 安装visual studio(vs)后无法安装SQLserver问题的成功解决
- .net core razor ajax,.NET CORE Razor Pages Ajax 调用 C# 方法
- SpringBoot中yaml配置
- Ionic 如何使用 Cordova 插件
- 解析:浏览器事件冒泡及事件捕获
- android这只椭圆背景,Android 背景样式shape - oval椭圆、圆
- ubuntu更改网卡设置等出现输入default keyring密码的解决方法
- 速腾激光雷达 xavier环境驱动配置踩坑记录
- 又是一道题拉开差距!IOI落幕,中国队三金一银,美国华人选手再获冠军
- 创建vue-ssr项目
- 学习KNN(一) 图像分类与KNN原理
- 您的连接不是私密连接 thisisunsafe
- Linux虚拟机不显示IP地址解决方法(亲测有效)
- 众多OA办公协同系统,企业应如何选择?
- super关键字什么时候使用?super的适用场景是?