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语言项目:学生成绩管理系统
C语言项目:学生成绩管理系统 1.数据结构:学生信息:学号.姓名.年龄.性别.3课成绩 2.功能: (1)增加学生记录 (2) 删除学生记录 (3) 查找学生信息(学号 ...
- jquery json实现二级动态联动
以下为代码!需要导入json架包 function getCity1(){ var unitid = document.getElementById('addformunitid').value; $ ...
- [leetcode]Binary Tree Preorder Traversal @ Python
原题地址:http://oj.leetcode.com/problems/binary-tree-preorder-traversal/ 题意:这题用递归比较简单.应该考察的是使用非递归实现二叉树的先 ...
- Pytoch 抽取中间层特征方法
定义一个特征提取的类: 参考pytorch论坛:How to extract features of an image from a trained model from torchvision.mo ...
- .NET-"/"应用程序中的服务器错误
当出现这个问题的时候,就在web.config文件中加上代码:<customErrors mode="Off"/> 然后重新访问站点就能看到问题所在了,例如我的错误显示 ...
- ntpdate设置
ntpdate设置 学习了:https://www.cnblogs.com/ibnode/p/3573302.html http://www.blogjava.net/spray/archive/20 ...
- Linux学习笔记之初级篇
第一部分:[安装注意环节] 第二部分:[常用命令小试] 第三部分:[oracle的安装]
- 【ACM】杭电ACM题一直WA求高手看看代码
数据测试了好几个都没问题,可以就是WA不让过,检测了2个小时还是没发现有什么问题T_T!!求高手看看代码,小弟在此谢谢各位哦! #include <stdio.h> #include &l ...
- Thrift 文件的格式及可用的数据类型
编写thrift文件是,须要知道thrift文件支持的数据类型有哪些.假设定义Service等.以下是官方文档的说明: # # Thrift Tutorial # Mark Slee (mcslee@ ...
- json的工具按照键进行排序
浏览器中,所有涉及json的工具会按照键进行排序,这个与实际的查询的数组的顺序有出入,见下图: