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

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

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

  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. [WPF 基础知识系列] —— 绑定中的数据校验Vaildation

    前言: 只要是有表单存在,那么就有可能有对数据的校验需求.如:判断是否为整数.判断电子邮件格式等等. WPF采用一种全新的方式 - Binding,来实现前台显示与后台数据进行交互,当然数据校验方式也 ...

  2. maven学习笔记--maven项目创建

    使用Maven命令和Eclipse的Maven插件,创建Maven项目 (1)maven命令生成项目         新建一个文件目录,dos进入该目录并执行下面命令: mvn archetype:c ...

  3. CSS实现DIV从隐藏到展示的过渡效果

    CSS中有很多功能强大的方法,其中过渡属性transition就很牛叉.你不用写一行JavaScript代码,随便写点css就可以实现一个动画效果.下面结合我在W3C网站上看到的实例,举个栗子说明下( ...

  4. SQL SERVER 2012/ 2014 分页,用 OFFSET,FETCH NEXT改写ROW_NUMBER的用法(转)

    写法: 假装有个表Shop,其中有一列ShopName,取100000到100050条数据. ROW_NUMBER 的写法 SELECT * FROM (SELECT ShopName , ROW_N ...

  5. Linux load average负载量分析与解决思路

    一.load average top命令中load average显示的是最近1分钟.5分钟和15分钟的系统平均负载.系统平均负载表示 系统平均负载被定义为在特定时间间隔内运行队列中(在CPU上运行或 ...

  6. 虚拟机克隆linux centos 6.5 系统网卡配置

    作为一个刚刚接触linux系统的小白来说,VMware虚拟机安装好CentOS6.5系统后,纯净的系统多克隆几份出来方便后期做试验.克隆步骤很简单,克隆后出现的问题是克隆后的网卡MAC地址和原系统MA ...

  7. CentOS7 中安装 MySQL

    0. 说明 参考 centos7.2安装MySQL CentOS 7 下 Yum 安装 MySQL 5.7 两种方式安装 MySQL 安装 MySQL(yum) & 安装 MySQL(yum) ...

  8. 【转】Java学习---算法那些事

    [更多参考] LeetCode算法 每日一题 1: Two Sum ----> 更多参考[今日头条--松鼠游学] 史上最全的五大算法总结 Java学习---7大经典的排序算法总结实现 程序员都应 ...

  9. git 命令行下浏览器tig使用记录

    git 命令行下浏览器tig使用记录 tig 是一款优化 git 命令行的工具,使 git 命令行更加的便捷人性化 .如果用习惯了,会上瘾. 以下是一些使用记录: 安装成功后,在 Repo 文件夹下, ...

  10. SQL server 数据库基本插入、删除命令

    一.实验素材: 附加学生信息表(student) 二.实验要求: 1.  查询student表中所有学生的信息 select  * from  student 2.  查询student表中“姓名”“ ...