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个部队维 ...
随机推荐
- 【转载】Visual Studio 2015 for Linux更好地支持Linux下的开发
原文:Visual Studio 2015 for Linux更好地支持Linux下的开发 英文原文:Targeting Linux Made Easier in Visual Studio 2015 ...
- Django 中的用户认证
Django 自带一个用户认证系统,这个系统处理用户帐户.组.权限和基于 cookie 的 会话.本文说明这个系统是如何工作的. 概览 认证系统由以下部分组成: 用户 权限:控制用户进否可以执行某项任 ...
- PHPwebshell分析
这几天已知在做webshell的检测,JSP的不说了,特征检测起来很好匹配到,而且全是一家亲,互相模仿的居多. 今天看了一篇文章,看到14年蘑菇的webshell的后门然后很不错. ========= ...
- dup2()函数的使用,
#define STR "xiamanman\n"#define STR_LEN 10#define STDOUT 1 #include <stdio.h>#inclu ...
- Native SQL
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- CUBRID学习笔记 19 sql语句1
创建 欢迎转载 ,转载时请保留作者信息.本文版权归本人所有,如有任何问题,请与我联系wang2650@sohu.com . 过错 create table tableName (字段名 字段类型 pr ...
- NPOI利用多任务模式分批写入多个Excel
接上文NPOI大数据分批写入同个Excel,这次是利用task多任务同时写入到多个Excel. Form2.cs private void btnExport_Click(object sender, ...
- C#中实现多继承的方法
有一个类叫老虎,还有一个类叫苍蝇.现在新创一个超级老虎类,一种可以飞的老虎,超级老虎由于同时也继承自苍蝇 namespace Interface { //飞的接口 public interface I ...
- java位运算符常见用法
1. 判断int型变量a是奇数还是偶数 a&1 = 0 偶数 a&1 = 1 奇数 2. 求平均值,比如有两个int类型变量x.y,首先要求x+y的和,再除以2,但是有可能x+y的结果 ...
- iOS - Swift NSKeyedArchiver 数据归档
前言 public class NSKeyedArchiver : NSCoder public class NSKeyedUnarchiver : NSCoder 在 OC 语言中,归档是一个过程, ...