SPFA 上手题 数 枚:
1, HDU 1548 A strange lift :http://acm.hdu.edu.cn/showproblem.php?pid=1548
这道题可以灰常巧妙的转换为一道最短路题目,对第i层,按钮数字为button[i],则如果满足相加<=N,则把i到i+button[i]的路径长度设为1(巧妙将按钮次数转换为路径长度),同理,相减如果满足>=1,则把i到i-button[i]的路径长度设为1.则最后输出终点的最短路的长度即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> using namespace std; const int INF=0x3f3f3f3f; int n,a,b;
int map[][],vis[],dis[]; int SPFA(){
for(int i=;i<=n;i++){
dis[i]=INF;
vis[i]=;
}
queue<int> q;
while(!q.empty())
q.pop();
dis[a]=;
vis[a]=;
q.push(a);
while(!q.empty()){
int cur=q.front();
q.pop();
vis[cur]=;
for(int i=;i<=n;i++)
if(dis[i]>dis[cur]+map[cur][i]){
dis[i]=dis[cur]+map[cur][i];
if(!vis[i]){
vis[i]=;
q.push(i);
}
}
}
return dis[b];
} int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d",&n) && n){
scanf("%d%d",&a,&b);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
map[i][j]=INF;
int x;
for(int i=;i<=n;i++){
scanf("%d",&x);
if(i-x>=)
map[i][i-x]=;
if(i+x<=n)
map[i][i+x]=;
}
int ans=SPFA();
if(ans==INF)
ans=-;
printf("%d\n",ans);
}
return ;
}
另附BFS解法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> using namespace std; int n,a,b;
int k[],vis[]; struct node{
int x,step;
}; int BFS(){
queue<node> q;
while(!q.empty())
q.pop();
node cur,next;
cur.x=a, cur.step=;
vis[cur.x]=;
q.push(cur);
while(!q.empty()){
cur=q.front();
q.pop();
if(cur.x==b)
return cur.step;
next.x=cur.x-k[cur.x];
next.step=cur.step+;
if(next.x>= && next.x<=n && !vis[next.x]){
vis[next.x]=;
q.push(next);
}
next.x=cur.x+k[cur.x];
if(next.x>= && next.x<=n && !vis[next.x]){
vis[next.x]=;
q.push(next);
}
}
return -;
} int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d",&n) && n){
scanf("%d%d",&a,&b);
for(int i=;i<=n;i++)
scanf("%d",&k[i]);
memset(vis,,sizeof(vis));
int ans=BFS();
printf("%d\n",ans);
}
return ;
}
2, HDU 3790 最短路径问题 : http://acm.hdu.edu.cn/showproblem.php?pid=3790
二维距离(路程,价格),优先判断路程…
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> using namespace std; const int VM=;
const int EM=;
const int INF=0x3f3f3f3f; struct Edge{
int to,nxt;
int cap,cost;
}edge[EM<<]; int n,m,cnt,head[VM];
int src,des,dis[VM],pay[VM],vis[VM]; void addedge(int cu,int cv,int cw,int cc){
edge[cnt].to=cv; edge[cnt].cap=cw; edge[cnt].cost=cc;
edge[cnt].nxt=head[cu]; head[cu]=cnt++;
} void SPFA(){
for(int i=;i<=n;i++){
dis[i]=INF;
pay[i]=INF;
vis[i]=;
}
queue<int> q;
while(!q.empty())
q.pop();
dis[src]=;
pay[src]=;
vis[src]=;
q.push(src);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].cap || (dis[v]==dis[u]+edge[i].cap && pay[v]>pay[u]+edge[i].cost)){ //二维距离(路程,价格),优先判断路程…
dis[v]=dis[u]+edge[i].cap;
pay[v]=pay[u]+edge[i].cost;
if(!vis[v]){
vis[v]=;
q.push(v);
}
}
}
}
} int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d%d",&n,&m)){
if(n== && m==)
break;
cnt=;
memset(head,-,sizeof(head));
int u,v,d,p;
while(m--){
scanf("%d%d%d%d",&u,&v,&d,&p);
addedge(u,v,d,p); //因为是无向边,所以建双向图
addedge(v,u,d,p);
}
scanf("%d%d",&src,&des);
SPFA();
printf("%d %d\n",dis[des],pay[des]);
}
return ;
}
3, HDU 2066 一个人的旅行 : http://acm.hdu.edu.cn/showproblem.php?pid=2066
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> using namespace std; const int INF=0x3f3f3f3f; struct Edge{
int to,nxt;
int cap;
}edge[]; int T,S,D;
int cnt,head[];
int src,des,dis[],vis[]; void addedge(int cu,int cv,int cw){
edge[cnt].to=cv; edge[cnt].cap=cw; edge[cnt].nxt=head[cu];
head[cu]=cnt++;
} int SPFA(){
queue<int> q;
while(!q.empty())
q.pop();
for(int i=;i<=;i++){
dis[i]=INF;
vis[i]=;
}
dis[src]=;
vis[src]=;
q.push(src);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].cap){
dis[v]=dis[u]+edge[i].cap;
if(!vis[v]){
vis[v]=;
q.push(v);
}
}
}
}
return dis[des];
} int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d%d%d",&T,&S,&D)){
cnt=;
memset(head,-,sizeof(head));
int u,v,w;
while(T--){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
src=, des=;
while(S--){
scanf("%d",&v);
addedge(src,v,);
}
while(D--){
scanf("%d",&u);
addedge(u,des,);
}
int ans=SPFA();
printf("%d\n",ans);
}
return ;
}
4, HDU 2112 HDU Today : http://acm.hdu.edu.cn/showproblem.php?pid=2112
trick:起点和终点有可能是同一点,坑爹呐。。。。。。。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue> using namespace std; const int N=;
const int INF=0x3f3f3f3f; struct Edge{
int to,nxt;
int cap;
}edge[N<<]; int all,cnt,head[N];
int src,des,dis[N],vis[N]; void addedge(int cu,int cv,int cw){
edge[cnt].to=cv; edge[cnt].cap=cw; edge[cnt].nxt=head[cu];
head[cu]=cnt++;
} int SPFA(){
queue<int> q;
while(!q.empty())
q.pop();
for(int i=;i<=all;i++){
dis[i]=INF;
vis[i]=;
}
dis[src]=;
vis[src]=;
q.push(src);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].cap){
dis[v]=dis[u]+edge[i].cap;
if(!vis[v]){
vis[v]=;
q.push(v);
}
}
}
}
return dis[des];
} int main(){ //freopen("input.txt","r",stdin); int n;
char str1[],str2[];
char s[],t[];
map<string,int> mp;
while(~scanf("%d",&n) && n!=-){
cnt=;
memset(head,-,sizeof(head));
all=;
mp.clear();
scanf("%s%s",s,t);
mp[s]=all++; //起点和终点有可能是同一点
src=mp[s];
if(mp[t]==)
mp[t]=all++;
des=mp[t];
int w;
while(n--){
scanf("%s%s%d",str1,str2,&w);
if(mp[str1]==)
mp[str1]=all++;
if(mp[str2]==)
mp[str2]=all++;
addedge(mp[str1],mp[str2],w);
addedge(mp[str2],mp[str1],w);
}
int ans=SPFA();
if(ans==INF)
ans=-;
printf("%d\n",ans);
}
return ;
}
SPFA 上手题 数 枚:的更多相关文章
- 值得一做》关于一道DP+SPFA的题 BZOJ1003 (BZOJ第一页计划) (normal-)
这是一道数据范围和评测时间水的可怕的题,只是思路有点难想,BUT假如你的思路清晰,完全了解怎么该做,那就算你写一个反LLL和反SLE都能A,如此水的一道题,你不心动吗? 下面贴出题目 Descript ...
- 【NOIP模拟赛】chess 建图+spfa统计方案数
似乎弗洛伊德和迪杰斯特拉都干不了统计方案数,spfa的话就是不断入队就好. #include <cstdio> #include <cstring> #include < ...
- 青岛理工ACM交流赛 J题 数格子算面积
数格子算面积 Time Limit: 1000MS Memory limit: 262144K 题目描述 给你一个多边形(用’\’和’/’表示多边形的边),求多边形的面积. 输入 第一行两个正整数h ...
- UVA 558 判定负环,spfa模板题
1.UVA 558 Wormholes 2.总结:第一个spfa,好气的是用next[]数组判定Compilation error,改成nexte[]就过了..难道next还是特殊词吗 题意:科学家, ...
- 水题2枚 Codevs1464&&Codevs1472
1472 体检 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 白银 Silver 题解 查看运行结果 题目描述 Description 郑厂长不是正厂长 也不是副厂长 ...
- poj 2586 Y2K Accounting Bug(贪心算法,水题一枚)
#include <iostream> using namespace std; /*248K 32MS*/ int main() { int s,d; while(cin>> ...
- POJ 半平面交 模板题 三枚
给出三个半平面交的裸题. 不会的上百度上谷(gu)歌(gou)一下. 毕竟学长的语文是体育老师教的.(卡格玩笑,别当真.) 这种东西明白就好,代码可以当模板. //poj1474 Video Surv ...
- NOIP2001-普及组复赛-第一题-数的计算
题目描述 Description 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 1.不作任何处理; 2.在 ...
- PAT甲题题解-1019. General Palindromic Number (20)-又是水题一枚
n转化为b进制的格式,问你该格式是否为回文数字(即正着写和倒着写一样)输出Yes或者No并且输出该格式又是水题... #include <iostream> #include <cs ...
随机推荐
- [转]C++之多态性与虚函数
面向对象程序设计中的多态性是指向不同的对象发送同一个消息,不同对象对应同一消息产生不同行为.在程序中消息就是调用函数,不同的行为就是指不同的实现方法,即执行不同的函数体.也可以这样说就是实现了“一个接 ...
- 通过java读取HDFS的数据 (转)
原文链接:通过java读取HDFS的数据 通过JAVA直接读取HDFS中的时候,一定会用到FSDataInputStream类,通过FSDataInputStream以流的形式从HDFS读数据代码如下 ...
- [leetcode]Sort List @ Python
原题地址:http://oj.leetcode.com/problems/sort-list/ 题意:链表的排序.要求:时间复杂度O(nlogn),空间复杂度O(1). 解题思路:由于题目对时间复杂度 ...
- SQL语句大小写是否区分的问题,批量修改整个数据库所有表所有字段大小写
一.实例介绍 SQL语句大小写到底是否区分呢?我们先从下面的这个例子来看一下: 例: --> 创建表,插入数据: declare @maco table (number int,myvalue ...
- Leaf - 一个由 Go 语言编写的开发效率和执行效率并重的开源游戏服务器框架
转自:https://toutiao.io/posts/0l7l7n/preview Leaf 游戏服务器框架简介 Leaf 是一个由 Go 语言(golang)编写的开发效率和执行效率并重的开源游戏 ...
- Oracle中的字符处理方法
向左补全字符串 lpad(字段名,填充长度,填充的字符) ,') from dual; 向右补全字符串 rpad(字段名,填充长度,填充的字符) ,') from dual; 返回字符串小写 sele ...
- MongoDB学习笔记(四)--索引 && 性能优化
索引 基础索引 ...
- 每日一水 POJ8道水题
1. POJ 3299 Humidex 链接: http://poj.org/problem?id=3299 这道题是已知H,D,T三者的运算关系,然后告诉你其中两个.求另一个. #include&l ...
- javascript深度克隆对象
/** * * @param obj * @returns {*} */ //深度克隆 function cloneObject(obj) { if (obj === null || typeof(o ...
- Linux之nohup命令:实现退出终端后程序继续后台运行
转自:http://tech.ccidnet.com/art/302/20070618/1115599_1.html 简单而有用的nohup命令在UNIX/LINUX中,普通进程用&符号放到后 ...