六道烦人的最短路(然而都是水题)

  我也不准备翻译题目了(笑)

  一些是最短路的变形(比如最长路,最短路中的最长边,判环),还有一些就是裸题了。

  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的更多相关文章

  1. 最短路(Bellman_Ford) POJ 1860 Currency Exchange

    题目传送门 /* 最短路(Bellman_Ford):求负环的思路,但是反过来用,即找正环 详细解释:http://blog.csdn.net/lyy289065406/article/details ...

  2. POJ 1860 Currency Exchange (最短路)

    Currency Exchange Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u S ...

  3. poj 1860 Currency Exchange (SPFA、正权回路 bellman-ford)

    链接:poj 1860 题意:给定n中货币.以及它们之间的税率.A货币转化为B货币的公式为 B=(V-Cab)*Rab,当中V为A的货币量, 求货币S通过若干此转换,再转换为原本的货币时是否会添加 分 ...

  4. POJ 1860 Currency Exchange / ZOJ 1544 Currency Exchange (最短路径相关,spfa求环)

    POJ 1860 Currency Exchange / ZOJ 1544 Currency Exchange (最短路径相关,spfa求环) Description Several currency ...

  5. POJ 1860——Currency Exchange——————【最短路、SPFA判正环】

    Currency Exchange Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u S ...

  6. poj - 1860 Currency Exchange Bellman-Ford 判断正环

    Currency Exchange POJ - 1860 题意: 有许多货币兑换点,每个兑换点仅支持两种货币的兑换,兑换有相应的汇率和手续费.你有s这个货币 V 个,问是否能通过合理地兑换货币,使得你 ...

  7. POJ 1860 Currency Exchange (Bellman-Ford)

    题目链接:POJ 1860 Description Several currency exchange points are working in our city. Let us suppose t ...

  8. POJ 1860 Currency Exchange + 2240 Arbitrage + 3259 Wormholes 解题报告

    三道题都是考察最短路算法的判环.其中1860和2240判断正环,3259判断负环. 难度都不大,可以使用Bellman-ford算法,或者SPFA算法.也有用弗洛伊德算法的,笔者还不会SF-_-…… ...

  9. POJ 1860(spfa)

    http://poj.org/problem?id=1860 题意:汇率转换,与之前的2240有点类似,不同的是那个题它去换钱的时候,是不需要手续费的,这个题是需要手续费的,这是个很大的不同. 思路: ...

随机推荐

  1. Flutter:修改TextField的高度,以及无边框圆角

    修改TextField的高度可以通过decoration: InputDecoration的contentPadding进行修改,代码如下 new TextField( decoration: Inp ...

  2. Android解析WindowManager(一)WindowManager体系

    前言 WindowManagerService(WMS)和AMS一样,都是Android开发需要掌握的知识点,同样的,WMS也很复杂,需要多篇文章来进行讲解,为何更好的理解WMS,首先要了解Windo ...

  3. [Android] 状态栏的一些认识

    前段时间遇到几个关于状态栏的问题,又了解了一下状态栏相关的知识,现在做一下记录. 本文地址:http://www.cnblogs.com/rossoneri/p/4316343.html 前戏和问题 ...

  4. LeetCode 题解之Add Digits

    1.问题描述 2.问题分析 循环拆分数字,然求和判断. 3.代码 int addDigits(int num) { ) return num; int result = num; do{ vector ...

  5. RBAC用户角色权限设计方案【转载】

    RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成“用户-角色- ...

  6. Oracle EBS OPM 查询现有量

    --查询现有量 --created by jenrry DECLARE p_inventory_item_id NUMBER := 231652; --NOT NULL p_organization_ ...

  7. 运维利器万能的 strace

    strace是什么? 按照strace官网的描述, strace是一个可用于诊断.调试和教学的Linux用户空间跟踪器.我们用它来监控用户空间进程和内核的交互,比如系统调用.信号传递.进程状态变更等. ...

  8. Year 2038 problem (2038年问题)

    From Wikipedia, the free encyclopedia       Animation showing how the date would reset, represented ...

  9. 【存在问题,待修改】SSH 远程登陆

    0. 前提 设置 hosts 参考链接 Linux 配置 hosts SSH公钥登录原理 1. SSH 是什么 SSH ( Secure Shell ) 是一种协议标准,其目的是实现安全远程登录以及其 ...

  10. oracle备份与恢复

    Oracle数据库有三种标准的备份方法,它们分别是导出/导入(EXP/IMP).热备份和冷备份.导出备件是一种逻辑备份,冷备份和热备份是物理备份. 导出/导入(Export/Import) 利用Exp ...