PAT (Advanced Level) Practise 1003 Emergency(SPFA+DFS)
1003. Emergency (25)
As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.
Input
Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) - the number of cities (and the cities are numbered from 0 to N-1), M - the number of roads, C1 and C2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.
Output
For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.
All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.
Sample Input
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
Sample Output
2 4
题目链接:1003 Emergency
点似乎不是很多,数据友好,最后一组7MS都能跑完,另外一种感觉麻烦一点但是适应性比较好做法是修改一下dij的写法加上dp的思想,然而不太懂,有空再看……
代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=510;
const int M=500010;
struct info
{
int to;
int pre;
int dx;
};
info E[M];
int head[M],ne;
int val[N],d[N],vis[N];
int maxm,ans,n,m,s,t;
void add(int s,int t,int d)
{
E[ne].to=t;
E[ne].pre=head[s];
E[ne].dx=d;
head[s]=ne++;
}
void init()
{
CLR(head,-1);
ne=0;
CLR(val,0);
CLR(d,INF);
ans=0;
maxm=0;
CLR(vis,0);
}
void spfa(int s)
{
int i;
priority_queue<pii>Q;
d[s]=0;
Q.push(pii(-d[s],s));
while (!Q.empty())
{
int now=Q.top().second;
Q.pop();
for (i=head[now]; ~i; i=E[i].pre)
{
int v=E[i].to;
if(d[v]>d[now]+E[i].dx)
{
d[v]=d[now]+E[i].dx;
Q.push(pii(-d[v],v));
}
}
}
}
void dfs(int now,int len,int ma)
{
int i;
if(now==t)
{
if(ma>maxm)
maxm=ma;
++ans;
return ;
}
for (i=head[now]; ~i; i=E[i].pre)
{
int v=E[i].to;
if(!vis[v]&&d[now]+E[i].dx==d[v])
{
vis[v]=1;
dfs(v,d[v],ma+val[v]);
vis[v]=0;
}
}
}
int main(void)
{
int x,y,z,i,j;
while (~scanf("%d%d%d%d",&n,&m,&s,&t))
{
init();
for (i=0; i<n; ++i)
scanf("%d",&val[i]);
for (i=0; i<m; ++i)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
spfa(s);
dfs(s,d[s],val[s]);
printf("%d %d\n",ans,maxm);
}
return 0;
}
———————10.13更新————————
学会了用Dijsktra来做,特地重新做了一下,发现这题有个坑就是边是双向的,单向边会错几组数据…………
Dij代码:
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=510;
const int M=1e6+7;
struct edge
{
int to;
int w;
int pre;
};
edge E[M];
int head[N],tot;
int d[N],vis[N],way[N],ans[N];
int man[N];
int n,m;
inline void add(int s,int t,int w)
{
E[tot].to=t;
E[tot].w=w;
E[tot].pre=head[s];
head[s]=tot++;
}
void init()
{
CLR(head,-1);
tot=0;
CLR(d,INF);
CLR(vis,0);
CLR(man,0);
CLR(way,0);
CLR(ans,0);
}
void Dij(int s)
{
int i,j,u,v,minm,w;
d[s]=0;
vis[s]=1;
way[s]=1;
ans[s]=man[s];
for (i=head[s]; ~i; i=E[i].pre)
{
v=E[i].to;
if(d[v]>E[i].w)
{
d[v]=E[i].w;
way[v]=1;
ans[v]=ans[s]+man[v];
}
}
for (i=1; i<n; ++i)
{
minm=INF;
u=-1;
for (j=0; j<n; ++j)
{
if(!vis[j]&&d[j]<minm)
{
minm=d[j];
u=j;
}
}
if(u==-1)
break;
vis[u]=1;
for (j=head[u]; ~j; j=E[j].pre)
{
v=E[j].to;
w=E[j].w;
if(d[v]>d[u]+w)
{
d[v]=d[u]+w;
way[v]=way[u];
ans[v]=ans[u]+man[v];
}
else if(d[v]==d[u]+w)
{
way[v]+=way[u];
ans[v]=max(ans[v],ans[u]+man[v]);
}
}
}
}
int main(void)
{
int a,b,w,s,t,i;
while (~scanf("%d%d%d%d",&n,&m,&s,&t))
{
init();
for (i=0; i<n; ++i)
scanf("%d",&man[i]);
for (i=0; i<m; ++i)
{
scanf("%d%d%d",&a,&b,&w);
add(a,b,w);
add(b,a,w);
}
Dij(s);
printf("%d %d\n",way[t],ans[t]);
}
return 0;
}
PAT (Advanced Level) Practise 1003 Emergency(SPFA+DFS)的更多相关文章
- PAT (Advanced Level) Practise 1003 解题报告
GitHub markdownPDF 问题描述 解题思路 代码 提交记录 问题描述 Emergency (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题 ...
- PAT (Advanced Level) Practice 1003 Emergency 分数 25 迪杰斯特拉算法(dijkstra)
As an emergency rescue team leader of a city, you are given a special map of your country. The map s ...
- PAT (Advanced Level) Practice 1003 Emergency
思路:用深搜遍历出所有可达路径,每找到一条新路径时,对最大救援人数和最短路径数进行更新. #include<iostream> #include<cstdio> #includ ...
- 1003 Emergency (25 分)
1003 Emergency (25 分) As an emergency rescue team leader of a city, you are given a special map of y ...
- 【PAT甲级】1003 Emergency (25 分)(SPFA,DFS)
题意:n个点,m条双向边,每条边给出通过用时,每个点给出点上的人数,给出起点终点,求不同的最短路的数量以及最短路上最多能通过多少人.(N<=500) AAAAAccepted code: #in ...
- PAT (Advanced Level) Practise 1004 解题报告
GitHub markdownPDF 问题描述 解题思路 代码 提交记录 问题描述 Counting Leaves (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 1600 ...
- PAT (Advanced Level) Practise - 1099. Build A Binary Search Tree (30)
http://www.patest.cn/contests/pat-a-practise/1099 A Binary Search Tree (BST) is recursively defined ...
- 【PAT甲级】1030 Travel Plan (30 分)(SPFA,DFS)
题意: 输入N,M,S,D(N,M<=500,0<S,D<N),接下来M行输入一条边的起点,终点,通过时间和通过花费.求花费最小的最短路,输入这条路径包含起点终点,通过时间和通过花费 ...
- 【PAT甲级】1018 Public Bike Management (30 分)(SPFA,DFS)
题意: 输入四个正整数C,N,S,M(c<=100,n<=500),分别表示每个自行车站的最大容量,车站个数,此次行动的终点站以及接下来的M行输入即通路.接下来输入一行N个正整数表示每个自 ...
随机推荐
- [Linux] AWK命令详解(大全)
转载自:http://caoyanbao.iteye.com/blog/570868 什么是awk? 你可能对UNIX比较熟悉,但你可能对awk很陌生,这一点也不奇怪,的确,与其优秀的功能相比,awk ...
- 菜鸟学SSH(十五)——简单模拟Hibernate实现原理
之前写了Spring的实现原理,今天我们接着聊聊Hibernate的实现原理,这篇文章只是简单的模拟一下Hibernate的原理,主要是模拟了一下Hibernate的Session类.好了,废话不多说 ...
- 最新php环境搭建
参考文章:http://jingyan.baidu.com/article/29697b912f6539ab20de3cf8.html
- UVa 11437:Triangle Fun(计算几何综合应用,求直线交点,向量运算,求三角形面积)
Problem ATriangle Fun Input: Standard Input Output: Standard Output In the picture below you can see ...
- Android VLC播放器二次开发1——程序结构分析
最近因为一个新项目需要一个多媒体播放器,所以需要做个视频.音频.图片方面的播放器.也查阅了不少这方面的资料,如果要从头做一个播放器工作量太大了,而且难度也很大.所以最后选择了VLC作为基础,进行二次开 ...
- hdu 5115 区间dp ***
题意:有n只狼,每只狼有两种属性,一种攻击力一种附加值,我们没杀一只狼,那么我们受到的伤害值为这只狼的攻击值与它旁边的两只狼的附加值的和,求把所有狼都杀光受到的最小的伤害值. 枚举中间k作为最后杀死的 ...
- hdu 5284 BestCoder Round #48 ($) 1001 水题 *
题意:看一个字符串中是否包含顺序的 w y h ,字符之间可以有其他字符,并且如果有多个连续的vv,则可以看做一个w 比较水,直接看代码 #include<cstdio> #incl ...
- hdu 3507 斜率dp
不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个 ...
- 能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。试图加载格式不正确的程序。
现象: 能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序.
- 在MongoDB中使用JOIN操作
SQL与NoSQL最大的不同之一就是不支持JOIN,在传统的数据库中,SQL JOIN子句允许你使用普通的字段,在两个或者是更多表中的组合表中的每行数据.例如,如果你有表books和publisher ...