POJ 1860&&3259&&1062&&2253&&1125&&2240
六道烦人的最短路(然而都是水题)
我也不准备翻译题目了(笑)
一些是最短路的变形(比如最长路,最短路中的最长边,判环),还有一些就是裸题了。
1860:找环,只需要把SPFA的松弛条件改一下即可,这里打的是BFS的。如果一个点入队次数大于n次,那么一定有环存在。
CODE
#include<cstdio>
#include<cstring>
using namespace std;
typedef double DB;
const int N=;
struct data
{
int to,next;
DB r,c;
}e[N*];
int head[N],q[N*N*],t[N],n,m,s,i,x,y,k=;
DB dis[N],v,r,c;
bool vis[N];
inline void add(int x,int y,DB r,DB c)
{
e[++k].to=y; e[k].r=r; e[k].c=c; e[k].next=head[x]; head[x]=k;
}
int main()
{
memset(head,-,sizeof(head));
memset(e,-,sizeof(e));
scanf("%d%d%d%lf",&n,&m,&s,&v);
for (i=;i<=m;++i)
{
scanf("%d%d%lf%lf",&x,&y,&c,&r);
add(x,y,r,c);
scanf("%lf%lf",&c,&r);
add(y,x,r,c);
}
int H=,T=;
dis[s]=v; q[]=s; vis[s]=t[s]=;
while (H<T)
{
int now=q[++H];
vis[now]=;
if (t[now]>n) { puts("YES"); return ; }
for (i=head[now];i!=-;i=e[i].next)
if (dis[e[i].to]<(dis[now]-e[i].r)*e[i].c)
{
dis[e[i].to]=(dis[now]-e[i].r)*e[i].c;
if (!vis[e[i].to])
{
q[++T]=e[i].to;
vis[e[i].to]=;
t[e[i].to]++;
}
}
}
puts("NO");
return ;
}
3259:几乎相同的SPFA判负环,这里写了DFS(判环比BFS的快)
CODE
#include<cstdio>
#include<cstring>
using namespace std;
const int N=;
struct data
{
int to,next,v;
}e[N];
int t,n,m,w,i,x,y,z,k,dis[N],vis[N],head[N];
bool flag;
inline void read(int &x)
{
x=; char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
inline void add(int x,int y,int z)
{
e[++k].to=y; e[k].v=z; e[k].next=head[x]; head[x]=k;
}
inline void SPFA(int now)
{
vis[now]=;
if (flag) return;
for (int i=head[now];i!=-;i=e[i].next)
if (dis[e[i].to]>dis[now]+e[i].v)
{
if (vis[e[i].to]) { flag=; return; }
dis[e[i].to]=dis[now]+e[i].v;
SPFA(e[i].to);
}
vis[now]=;
}
int main()
{
read(t);
while (t--)
{
memset(e,-,sizeof(e));
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
read(n); read(m); read(w);
k=flag=;
for (i=;i<=m;++i)
{
read(x); read(y); read(z);
add(x,y,z); add(y,x,z);
}
for (i=;i<=w;++i)
{
read(x); read(y); read(z);
add(x,y,-z);
}
for (i=;i<=n;++i)
{
if (flag) break;
memset(dis,,sizeof(dis));
SPFA(i);
}
if (flag) puts("YES"); else puts("NO");
}
return ;
}
1062:枚举+SPFA,感觉SPFA写起来比DJ舒服,DJ还要开个堆。
对于等级的限制我们只需要枚举等级的左右端点即可。
CODE
#include<cstdio>
#include<cstring>
using namespace std;
const int N=;
struct data
{
int to,next,v;
}e[N*N];
int head[N],dis[N],vis[N],lev[N],v[N],q[N*],t,n,c,k,i,j,num,p,l,r,ans=1e9;
inline void read(int &x)
{
x=; char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
inline void add(int x,int y,int z)
{
e[++k].to=y; e[k].v=z; e[k].next=head[x]; head[x]=k;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline int SPFA(int s)
{
memset(dis,,sizeof(dis));
dis[s]=; vis[s]=; q[]=s;
int H=,T=,res=1e9;
while (H<T)
{
int now=q[++H];
vis[now]=;
for (int i=head[now];i!=-;i=e[i].next)
if (lev[e[i].to]>=l&&lev[e[i].to]<=r)
if (dis[e[i].to]>dis[now]+e[i].v)
{
dis[e[i].to]=dis[now]+e[i].v;
if (!vis[e[i].to]) q[++T]=e[i].to,vis[e[i].to]=;
}
}
for (int i=;i<=n;++i)
res=min(res,dis[i]+v[i]);
return res;
}
int main()
{
memset(e,-,sizeof(e));
memset(head,-,sizeof(head));
read(t); read(n);
for (i=;i<=n;++i)
{
read(v[i]); read(lev[i]); read(c);
for (j=;j<=c;++j)
{
read(num); read(p);
add(i,num,p);
}
}
for (i=;i<=t+;++i)
{
l=lev[]+i--t; r=lev[]+i-;
ans=min(ans,SPFA());
}
printf("%d",ans);
return ;
}
2253:求最短路中的最长边—>写DJ,改松弛条件—>炸了,改写最小生成树(Kruskal)找最短边
其实图论题重在建模!
CODE
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef double DB;
const int N=,INF=1e9;
struct data
{
int x,y;
DB s;
}e[N*N];
int father[N],x[N],y[N],c,n,i,j,k;
DB ans;
inline void read(int &x)
{
x=; char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
inline DB calc(int a,int b)
{
return sqrt((double)(x[a]-x[b])*(x[a]-x[b])+(double)(y[a]-y[b])*(y[a]-y[b]));
}
inline void add(int x,int y,DB z)
{
e[++k].x=x; e[k].y=y; e[k].s=z;
}
inline int comp(data a,data b)
{
return a.s<b.s;
}
inline int getfather(int k)
{
return father[k]==k?k:father[k]=getfather(father[k]);
}
int main()
{
for (;;)
{
read(n);
if (!n) break;
k=ans=;
for (i=;i<=n;++i)
read(x[i]),read(y[i]),father[i]=i;
for (i=;i<n;++i)
for (j=i+;j<=n;++j)
add(i,j,calc(i,j)),add(j,i,calc(i,j));
sort(e+,e+k+,comp);
for (i=;i<=k;++i)
{
int fx=getfather(e[i].x),fy=getfather(e[i].y);
if (getfather()==getfather()) break;
if (fx!=fy)
{
father[fx]=fy;
ans=e[i].s;
}
}
printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++c,ans);
}
}
1125:最短路模板题,不过要枚举起点再跑SPFA(话说这是Floyd能解决的事,但我发现我好像不会Floyd了)
CODE
#include<cstdio>
#include<cstring>
using namespace std;
const int N=,INF=1e9;
struct data
{
int to,next,v;
}e[N*N];
int dis[N],head[N],q[N*N*],n,i,j,m,k,x,y,ans,num;
bool vis[N];
inline void read(int &x)
{
x=; char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
inline void add(int x,int y,int z)
{
e[++k].to=y; e[k].v=z; e[k].next=head[x]; head[x]=k;
}
int main()
{
for (;;)
{
read(n);
if (!n) break;
ans=INF; num=k=;
memset(e,-,sizeof(e));
memset(head,-,sizeof(head));
for (i=;i<=n;++i)
{
read(m);
for (j=;j<=m;++j)
{
read(x); read(y);
add(i,x,y);
}
}
for (i=;i<=n;++i)
{
for (j=;j<=n;++j)
dis[j]=INF;
memset(vis,,sizeof(vis));
dis[i]=; vis[i]=; q[]=i;
int H=,T=;
while (H<T)
{
int now=q[++H];
vis[now]=;
for (j=head[now];j!=-;j=e[j].next)
{
if (dis[e[j].to]>dis[now]+e[j].v)
{
dis[e[j].to]=dis[now]+e[j].v;
if (!vis[e[j].to]) q[++T]=e[j].to,vis[e[j].to]=;
}
}
}
int res=;
for (j=;j<=n;++j)
if (dis[j]>res) res=dis[j];
if (res<ans) ans=res,num=i;
}
if (ans==INF) puts("disjoint"); else printf("%d %d\n",num,ans);
}
}
2240:同样的货币兑换,也是找环的过程。这里对于字符串懒得写hash了,直接开了map
CODE
#include<cstdio>
#include<map>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
typedef double DB;
const int N=;
map <string,int> hash;
struct data
{
int to,next;
DB v;
}e[N*N];
string s1,s2;
DB dis[N],v;
int head[N],n,i,k,m,t;
bool vis[N],flag;
inline void read(int &x)
{
x=; char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
inline void add(int x,int y,DB z)
{
e[++k].to=y; e[k].v=z; e[k].next=head[x]; head[x]=k;
}
inline void SPFA(int now)
{
if (flag) return;
vis[now]=;
for (int i=head[now];i!=-;i=e[i].next)
if (dis[e[i].to]<dis[now]*e[i].v)
{
if (vis[e[i].to]) { flag=; return; }
dis[e[i].to]=dis[now]*e[i].v;
SPFA(e[i].to);
}
vis[now]=;
}
int main()
{
for (;;)
{
read(n);
if (!n) break;
memset(e,-,sizeof(e));
memset(head,-,sizeof(head));
k=flag=;
for (i=;i<=n;++i)
{
cin>>s1;
hash[s1]=i;
}
read(m);
for (i=;i<=m;++i)
{
cin>>s1; scanf("%lf",&v); cin>>s2;
add(hash[s1],hash[s2],v);
}
for (i=;i<=n;++i)
{
if (flag) break;
memset(dis,,sizeof(dis));
memset(vis,,sizeof(vis));
dis[i]=;
SPFA(i);
}
if (flag) printf("Case %d: Yes\n",++t); else printf("Case %d: No\n",++t);
}
return ;
}
准备结束图论专题!
POJ 1860&&3259&&1062&&2253&&1125&&2240的更多相关文章
- 最短路(Bellman_Ford) POJ 1860 Currency Exchange
题目传送门 /* 最短路(Bellman_Ford):求负环的思路,但是反过来用,即找正环 详细解释:http://blog.csdn.net/lyy289065406/article/details ...
- POJ 1860 Currency Exchange (最短路)
Currency Exchange Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u S ...
- poj 1860 Currency Exchange (SPFA、正权回路 bellman-ford)
链接:poj 1860 题意:给定n中货币.以及它们之间的税率.A货币转化为B货币的公式为 B=(V-Cab)*Rab,当中V为A的货币量, 求货币S通过若干此转换,再转换为原本的货币时是否会添加 分 ...
- POJ 1860 Currency Exchange / ZOJ 1544 Currency Exchange (最短路径相关,spfa求环)
POJ 1860 Currency Exchange / ZOJ 1544 Currency Exchange (最短路径相关,spfa求环) Description Several currency ...
- POJ 1860——Currency Exchange——————【最短路、SPFA判正环】
Currency Exchange Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u S ...
- poj - 1860 Currency Exchange Bellman-Ford 判断正环
Currency Exchange POJ - 1860 题意: 有许多货币兑换点,每个兑换点仅支持两种货币的兑换,兑换有相应的汇率和手续费.你有s这个货币 V 个,问是否能通过合理地兑换货币,使得你 ...
- POJ 1860 Currency Exchange (Bellman-Ford)
题目链接:POJ 1860 Description Several currency exchange points are working in our city. Let us suppose t ...
- POJ 1860 Currency Exchange + 2240 Arbitrage + 3259 Wormholes 解题报告
三道题都是考察最短路算法的判环.其中1860和2240判断正环,3259判断负环. 难度都不大,可以使用Bellman-ford算法,或者SPFA算法.也有用弗洛伊德算法的,笔者还不会SF-_-…… ...
- POJ 1860(spfa)
http://poj.org/problem?id=1860 题意:汇率转换,与之前的2240有点类似,不同的是那个题它去换钱的时候,是不需要手续费的,这个题是需要手续费的,这是个很大的不同. 思路: ...
随机推荐
- Android之编写测试用例
测试是软件工程中一个非常重要的环节,而测试用例又可以显著地提高测试的效率和准确性.测试用例其实就是一段普通的程序代码,通常是带有期望的运行结果的,测试者可以根据最终的运行结果来判断程序是否能正常工作. ...
- C#取得控制台应用程序的根目录方法 判断文件夹是否存在,不存在就创建
取得控制台应用程序的根目录方法1:Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径2:AppDomain.CurrentDomain.BaseDirect ...
- C#安全加密类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.S ...
- man -k : nothing appropriate.
➜ workplace man -k zip zip: nothing appropriate. 出现这种情况,是索引库没有建立. man 和 whatis 共用一个索引库的. 我们使用 man w ...
- MySQL 的 CURD 操作
0. 说明 CURD 操作通常是使用关系型数据库系统中的结构化查询语言(Structured Query Language,SQL)完成的 CURD 定义了用于处理数据的基本原子操作 CURD 代表创 ...
- 【转】Java学习---10个测试框架介绍
[原文]https://www.toutiao.com/i6594302925458113027/ JAVA 程序员需要用到 10 个测试框架和库 Java 程序员需要用到十大单元测试和自动化集成测试 ...
- Windows窗体数据抓取详解
最近在客户项目上刚好遇到一个问题,项目需求是要获取某台机床的实时状态,问题点刚好就在于该机床不是传统意义上的数控机床,也不是PLC控制器,只有一个上传下载程序文件的应用程序,上面刚好有几个按钮可以大概 ...
- MySQL基础之 AND和OR运算符
AND和OR运算符 作用:用于基于一个以上的条件对记录进行过滤 用法:可在WHERE子句中把两个或多个条件结合在一起. AND:如果第一个条件和第二个条件都成立,才会显示一条记录 OR:如果第一个条件 ...
- python + pyqt5 QlineEdit QMessageBox实现信息录入和消息弹框提醒
本人现在在做自动化工具开发的工作,因此,记录下自己平时遇到的问题和解决之道,还有一些简单的小工具 以下为主代码 # --*-- coding:utf-8 --*-- from first import ...
- vue+axios自己踩过的坑
axios的介绍就不用了吧,api有具体的介绍axios或者是axios中文: 主要讲的就是我自己在第一次使用axios中遇到的问题,及二次封装 先来说说二次封装,之前自己也是网上找了很多同学的封装, ...