nyoj 115------城市平乱( dijkstra // bellman )
城市平乱
- 描述
-
南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市。
他在用这N个部队维护着M个城市的治安,这M个城市分别编号从1到M。
现在,小工军师告诉南将军,第K号城市发生了暴乱,南将军从各个部队都派遣了一个分队沿最近路去往暴乱城市平乱。
现在已知在任意两个城市之间的路行军所需的时间,你作为南将军麾下最厉害的程序员,请你编写一个程序来告诉南将军第一个分队到达叛乱城市所需的时间。
注意,两个城市之间可能不只一条路。
- 输入
- 第一行输入一个整数T,表示测试数据的组数。(T<20)
每组测试数据的第一行是四个整数N,M,P,Q(1<=N<=100,N<=M<=1000,M-1<=P<=100000)其中N表示部队数,M表示城市数,P表示城市之间的路的条数,Q表示发生暴乱的城市编号。
随后的一行是N个整数,表示部队所在城市的编号。
再之后的P行,每行有三个正整数,a,b,t(1<=a,b<=M,1<=t<=100),表示a,b之间的路如果行军需要用时为t数据保证暴乱的城市是可达的。
- 输出
- 对于每组测试数据,输出第一支部队到达叛乱城市时的时间。每组输出占一行
- 样例输入
-
1
3 8 9 8
1 2 3
1 2 1
2 3 2
1 4 2
2 5 3
3 6 2
4 7 1
5 7 3
5 8 2
6 8 2 - 样例输出
-
4
- 来源
- 《世界大学生程序设计竞赛高级教程·第一册》改编
- 代码:
- 运用最简单的邻接矩阵+狄斯喹诺算法来做题目
- 代码为:
-
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
const int maxn=;
const int inf=0x3f3f3f3f;
int cost[maxn][maxn];
int path[maxn],lowc[maxn];
bool vis[maxn];
void Dijkstra(int n,int st)
{
int i,j,minc;
memset(vis,,sizeof(vis));
vis[st]= ;
for(i=;i<n;i++)
{
lowc[i]=cost[st][i];
path[i]=st;
}
lowc[st]=;
path[st]=-; //树根的标记
int pre=st;
for(i=;i<n;i++)
{
minc=inf;
for(j=;j<n;j++)
{
if(vis[j]==&&lowc[pre]+cost[pre][j]<lowc[j])
{
lowc[j]=lowc[pre]+cost[pre][j];
path[j]=pre;
}
}
for(j=;j<n;j++)
{
if(vis[j]==&&lowc[j]<minc)
{
minc=lowc[j];
pre=j;
}
}
vis[pre]=;
}
}
int groop[];
int main()
{
int n,m,p,q,i,j;
int a,b,c,test,res;
// freopen("test.in","r",stdin);
scanf("%d",&test);
while(test--)
{
scanf("%d%d%d%d",&n,&m,&p,&q);
for(i=;i<n;i++)
scanf("%d",&groop[i]);
for(i=;i<m;i++)
for(j=;j<m;j++)
cost[i][j]=inf;
for(i=;i<p;i++)
{
scanf("%d%d%d",&a,&b,&c);
a-- , b-- ;
if(cost[a][b]>c||cost[a][b]==)
cost[a][b]=cost[b][a]=c;
}
Dijkstra(m,q-);
res=inf;
for(i=;i<n;i++)
{
if(res>lowc[groop[i]-])
res=lowc[groop[i]-];
}
printf("%d\n",res);
}
return ;
}采用bellman算法求最短路 裸的算法
代码:
/*bellman求最短路*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
using namespace std; const int inf=0x3f3f3f3f;
int m,n,p,q,pre[],edge[][];
int dist[]; int relax(int u ,int v ,int c)
{
if(dist[v]>dist[u]+c)
{
dist[v]=dist[u]+c;
pre[v]=u;
return ;
}
return ;
} int bellman(int st)
{
int i,j;
for(i=;i<=m;i++){
dist[i]=inf;
pre[i]=-;
}
dist[st]=;
bool flag;
for(i=;i<m;i++)
{
flag=false; //优化
for(j=;j<=*p;j++)
{
if(==relax(edge[j][],edge[j][],edge[j][]))
flag=true;
}
if(!flag) break;
}
for(j=;j<=*p;j++)
{
if(==relax(edge[j][],edge[j][],edge[j][]))
return ; //有负圈
}
return ;
}
int groop[];
int main()
{
int test,i,j;
// freopen("test.in","r",stdin);
scanf("%d",&test);
while(test--)
{
scanf("%d%d%d%d",&n,&m,&p,&q);
for(i=;i<n;i++)
scanf("%d",&groop[i]);
for(i=;i<=p;i++)
{
//建立无向图
scanf("%d%d%d",&edge[i][],&edge[i][],&edge[i][]);
edge[p+i][]=edge[i][];
edge[p+i][]=edge[i][];
edge[p+i][]=edge[i][];
}
bellman(q);
int res=inf;
for(i=;i<n;i++)
{
if(res>dist[groop[i]])
res=dist[groop[i]];
}
printf("%d\n",res);
}
return ;
} - 采用bellman优化的算法即SPFA进行求解:
- 代码如下:
- 套用模板居然错了,还有比这更扯的嘛!!!
- 邻接表+狄斯喹诺算法
- RuntimeError
-
/*狄斯喹诺算法*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#pragma comment(linker, "/STACK:102400000,102400000") const int inf=0x3f3f3f3f;
using namespace std ; int cost[],dist[];
int e,pnt[],next[],head[],prev[],vis[];
int groop[]; struct node
{
int v,c;
node ( int vv= , int cc= ) : v(vv),c(cc){}
bool operator < ( const node &r ) const
{
return c>r.c ;
}
}; void dijkstra (int n ,const int src)
{
node mv;
int i,j,k,pre;
priority_queue<node> que;
vis[src]=;
dist[src]=;
que.push(node(src,));
for(pre=src,i=;i<n;i++)
{
for(j=head[pre];j!=-;j=next[j])
{
k=pnt[j];
if(vis[k]==&&dist[pre]+cost[j]<dist[k])
{
dist[k]=dist[pre]+cost[k];
que.push(node(pnt[j] , dist[k]));
prev[k]=pre;
}
} while(!que.empty()&&vis[que.top().v]==)
que.pop();
if(que.empty()) break;
mv=que.top();
que.pop();
vis[mv.v]=;
pre=mv.v; }
} inline void addedge(int u , int v , int c)
{
//面对重边又该怎么办 pnt[e]=v;
cost[e]=c;
next[e]=head[u];
head[u]=e++;
} void init(int nv ,int ne)
{
int i,u,v,c;
e=;
memset( head , - , sizeof(head) );
memset( vis , , sizeof(vis) );
memset( prev , - , sizeof(prev) );
memset(pnt,,sizeof(pnt));
for(i=;i<nv;i++)
dist[i]=inf;
// 如 何 应 对 重 边
for(i=;i<ne;i++)
{
scanf("%d%d%d",&u,&v,&c);
u-- ;
v-- ;
addedge(u,v,c);
addedge(v,u,c);
}
} int main()
{
int test,i;
int n,m,p,q;
scanf("%d",&test);
while(test--)
{
memset(cost,-,sizeof(cost));
scanf("%d%d%d%d",&n,&m,&p,&q);
for(i=;i<n;i++)
scanf("%d",&groop[i]);
init(p,p);
dijkstra(n,q-);
int res=inf;
for(i=;i<n;i++)
if(res>dist[groop[i]-])
res=dist[groop[i]-];
printf("%d\n",res);
}
return ;
}
nyoj 115------城市平乱( dijkstra // bellman )的更多相关文章
- nyoj 115 城市平乱 dijkstra最短路
题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=115 dijkstra算法. #include "stdio.h" ...
- nyoj 115 城市平乱
城市平乱 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维护着M个城市的治安,这M个城市 ...
- NYOJ 115 城市平乱 (最短路)
* 题目链接* 描述 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维护着M个城市的治安,这M个城市分别编号从1到M. 现在,小工军师告诉南将军,第K号城市发生了暴乱,南 ...
- nyist oj 115 城市平乱 (最短路径)
城市平乱 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描写叙述 南将军统领着N个部队.这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维护着M个城市的治安.这M个城市 ...
- 南洋理工 OJ 115 城市平乱 dijstra算法
城市平乱 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维护着M个城市的治安,这M个城市 ...
- 城市平乱 ---- Dijkstra
题解 : 以暴乱城市 为 源点 向所有点做最短路径 , 然后检查每个不对到暴乱城市的 最短距离 #include<stdio.h> #include<string.h> #in ...
- 城市平乱(Bellman)
城市平乱 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维护着M个城市的治安,这M个城市 ...
- Nyoj 城市平乱(图论)
描述 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维护着M个城市的治安,这M个城市分别编号从1到M. 现在,小工军师告诉南将军,第K号城市发生了暴乱,南将军从各个部队都 ...
- nyoj 115-城市平乱 (BFS)
115-城市平乱 内存限制:64MB 时间限制:1000ms 特判: No 通过数:5 提交数:8 难度:4 题目描述: 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维 ...
随机推荐
- UVA 1424 二 Salesmen
Salesmen Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Pr ...
- linux终端下为什么用命令打开软件后,要关闭软件才能继续下一条命令?
用终端打开chromium浏览器(命令:chromium-browser)的时候发现打开浏览器之后无法继续在终端输入命令,只能关闭浏览器或者在终端按下Ctrl+c,此时系统将退出浏览器并可以继续在终端 ...
- 对MSP430单片机__delay_cycles精确延时的说明及改正
在这里, 我来讨论一下关于MSP430单片机使用__delay_cycles延时的问题. IAR for MSP430编译器提供了一个编译器内联的精确延时函数(并非真正的函数)以提供用户精确延时使用, ...
- LINQ之路 5:LINQ查询表达式
书写LINQ查询时又两种语法可供选择:方法语法(Fluent Syntax)和查询表达式(Query Expression). LINQ方法语法的本质是通过扩展方法和Lambda表达式来创建查询.C# ...
- spring的自动装配(default-autowire="byName")
自动装配,官方给出的定义是这样:Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系.因此,如果可能的话,可以自 动让Spring通过检查BeanFactory中的内 ...
- centos下安装nginx和php-fpm
安装这两个花了大约七个小时,简直呵呵,安装nginx就是直接 yum install nginx ,但发现一打开php文件就是直接下载该php文件,也就是不能识别php文件,解决这个花了好久,但其实看 ...
- iOS - Swift Subscript 下标脚本
1.Subscript 下标脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值.语法类似于实例方法和计算型属性的混合.与定义实例方法类似,定义下标脚本使用 subscri ...
- iOS - UIActionSheet
前言 NS_CLASS_DEPRECATED_IOS(2_0, 8_3, "UIActionSheet is deprecated. Use UIAlertController with a ...
- [转载] Linux 文件系统结构介绍
原文: https://linux.cn/article-6132-weibo.html Linux中的文件是什么?它的文件系统又是什么?那些配置文件又在哪里?我下载好的程序保存在哪里了?在 Linu ...
- FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_REORDER_TO_FRONT用法
Activity的两种启动模式: FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_REORDER_TO_FRONT 1. 如果已经启动了四个Activity:A,B,C和D ...