Tram
Time Limit: 1000MS
Description
Tram network in Zagreb consists of anumber of intersections and rails connecting some of them. In everyintersection there is a switch pointing to the one of the rails going out ofthe intersection. When the tram enters the intersection it can leave only inthe direction the switch is pointing. If the driver wants to go some other way,he/she has to manually change the switch.
When a driver has do drive from intersection A to the intersection B he/shetries to choose the route that will minimize the number of times he/she willhave to change the switches manually.
Write a program that will calculate the minimal number of switch changesnecessary to travel from intersection A to intersection B.
Input
The first line of theinput contains integers N, A and B, separated by a single blank character, 2<= N <= 100, 1 <= A, B <= N, N is the number of intersections inthe network, and intersections are numbered from 1 to N.
Each of the following N lines contain a sequence of integers separated by asingle blank character. First number in the i-th line, Ki (0 <= Ki <=N-1), represents the number of rails going out of the i-th intersection. NextKi numbers represents the intersections directly connected to the i-thintersection.Switch in the i-th intersection is initially pointing in thedirection of the first intersection listed.
Output
The first and onlyline of the output should contain the target minimal number. If there is noroute from A to B the line should contain the integer "-1".
SampleInput
3 2 1
2 2 3
2 3 1
2 1 2
SampleOutput
0
Source
Croatia OI 2002 Regional -Juniors
题解:
题目的大致内容是:给定一个有向无环图,求源点到终点的距离最短。
很裸的一个最短路,刚好来测试。
//Floyd(); // O(v^3) 16 ms
//Dijkstra_A(); // O(v*e) 0 ms
//Dijkstra_B(); // O((v+e)log e) 0 ms
//BellmanFord(); // O(v*e) 0 ms
//Spfa_A(); // O(ke) 16 ms
//Spfa_B(); // O(ke) 0 ms
首先是floyd算法,本来是用来求多源的,但是题目数据太弱,所以。。呵呵,顺便也能求。O( n^3 )的复杂度。必然时间很多。
下来是不优化的dijkstra,时间复杂度是O(v*e) ,已经可以0ms过了。
再来是用堆优化的dijkstra,利用的是效率比较低的STL中的priority_queue,已经。。0ms
后面的是bellmamford,和不优化的dijkstra是一个时间复杂度。但是可以处理负环问题,明显优于dijkstra的不优化版本。0ms。
下面是bellmanford的队列优化算法,即spfa算法的普通版,O(ke)的时间复杂度,k经过验证一般小于2,这时间复杂度的确和他的名字相符。。敢叫做ShortestPathFasterAlgorithm,肯定有过人之处,作为中国人发明的算法,必须顶。。。。但是。很明显STL的queue时间复杂度。。。呵呵。。。16ms还是裸写queue吧
Time Limit: 1000MS
Memory Limit: 30000K
Total Submissions: 8553Description
Tram network in Zagreb consists of anumber of intersections and rails connecting some of them. In everyintersection there is a switch pointing to the one of the rails going out ofthe intersection. When the tram enters the intersection it can leave only inthe direction the switch is pointing. If the driver wants to go some other way,he/she has to manually change the switch.
When a driver has do drive from intersection A to the intersection B he/shetries to choose the route that will minimize the number of times he/she willhave to change the switches manually.
Write a program that will calculate the minimal number of switch changesnecessary to travel from intersection A to intersection B.
Input
The first line of theinput contains integers N, A and B, separated by a single blank character, 2<= N <= 100, 1 <= A, B <= N, N is the number of intersections inthe network, and intersections are numbered from 1 to N.
Each of the following N lines contain a sequence of integers separated by asingle blank character. First number in the i-th line, Ki (0 <= Ki <=N-1), represents the number of rails going out of the i-th intersection. NextKi numbers represents the intersections directly connected to the i-thintersection.Switch in the i-th intersection is initially pointing in thedirection of the first intersection listed.
Output
The first and onlyline of the output should contain the target minimal number. If there is noroute from A to B the line should contain the integer "-1".
SampleInput
3 2 1
2 2 3
2 3 1
2 1 2
SampleOutput
0
Source
Croatia OI 2002 Regional -Juniors
题解:
题目的大致内容是:给定一个有向无环图,求源点到终点的距离最短。
很裸的一个最短路,刚好来测试。
//Floyd(); // O(v^3) 16 ms
//Dijkstra_A(); // O(v*e) 0 ms
//Dijkstra_B(); // O((v+e)log e) 0 ms
//BellmanFord(); // O(v*e) 0 ms
//Spfa_A(); // O(ke) 16 ms
//Spfa_B(); // O(ke) 0 ms
首先是floyd算法,本来是用来求多源的,但是题目数据太弱,所以。。呵呵,顺便也能求。O( n^3 )的复杂度。必然时间很多。
下来是不优化的dijkstra,时间复杂度是O(v*e) ,已经可以0ms过了。
再来是用堆优化的dijkstra,利用的是效率比较低的STL中的priority_queue,已经。。0ms
后面的是bellmamford,和不优化的dijkstra是一个时间复杂度。但是可以处理负环问题,明显优于dijkstra的不优化版本。0ms。
下面是bellmanford的队列优化算法,即spfa算法的普通版,O(ke)的时间复杂度,k经过验证一般小于2,这时间复杂度的确和他的名字相符。。敢叫做ShortestPathFasterAlgorithm,肯定有过人之处,作为中国人发明的算法,必须顶。。。。但是。很明显STL的queue时间复杂度。。。呵呵。。。16ms还是裸写queue吧
最后登场的是用slf优化的spfa。。。时间复杂度理论值还是O(ke),但是实际上是有很明显的优化效率的。在使用慢的要死的STL deque的情况下,依然表现完美。0 ms。
源代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#define INF 999999
#define N 110
using namespace std;
class Node{
public :
int x,z,y;
friend bool operator >(const Node &p,const Node &q){
return (p.z>q.z);
}
}ss,bf[N*N];
priority_queue <Node,vector<Node>,greater<Node> > sp;
int a[N+1][N+1];
int f[N+1];
int n,s,e,m,num;
queue <int> pa;
deque <int> ap;
int dis[N+1];
void readin(){
scanf("%d%d%d",&n,&s,&e);
int i,j;
int x,y;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
a[i][j]=INF;
for (i=1;i<=n;i++){
scanf("%d",&m);
for (j=1;j<=m;j++){
scanf("%d",&x);
if (j==1) a[i][x]=0;
else
a[i][x]=1;
ss.x=i,ss.z=a[i][x],ss.y=x;
bf[++num]=ss;
}
}
for (i=1;i<=n;i++){
ss.x=i,ss.z=a[s][i];
dis[i]=INF;
sp.push(ss);
}
}
void Floyd(){
int i,j,k;
for (k=1;k<=n;k++)
for (i=1;i<=n;i++)
for (j=1;j<=n;j++){
if (a[i][k]<INF && a[k][j]<INF){
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
}
}
if (a[s][e]==INF) puts("-1");
else
printf("%d\n",a[s][e]);
}
void Dijkstra_A(){
memset(f,0,sizeof(f));
f[s]=1;
int i,k;
int mm;
int w;
for (k=1;k<n;k++){
mm=INF;
for (i=1;i<=n;i++){
if (!f[i] && a[s][i]<=mm){
mm=a[s][i];
w=i;
}
}
f[w]=1;
for (i=1;i<=n;i++){
if (!f[i] && a[s][w]<INF && a[w][i]<INF){
a[s][i]=min(a[s][i],a[s][w]+a[w][i]);
}
}
}
if (a[s][e]==INF) puts("-1");
else
printf("%d\n",a[s][e]);
}
void Dijkstra_B(){
memset(f,0,sizeof(f));
f[s]=1;
int i,k;
int mm;
int w;
for (k=1;k<n;k++){
while (f[sp.top().x]) sp.pop();
f[sp.top().x]=1;
for (i=1;i<=n;i++){
if (!f[i] && a[s][sp.top().x]+a[sp.top().x][i]<a[s][i]){
a[s][i]=a[s][sp.top().x]+a[sp.top().x][i];
ss.x=i,ss.z=a[s][i];
sp.push(ss);
}
}
}
if (a[s][e]==INF) puts("-1");
else
printf("%d\n",a[s][e]);
}
void BellmanFord(){
int i,j;
for (i=1;i<n;i++){
for (j=1;j<=num;j++){
a[s][bf[j].y]=min(a[s][bf[j].x]+bf[j].z,a[s][bf[j].y]);
}
}
if (a[s][e]==INF) puts("-1");
else
printf("%d\n",a[s][e]);
}
void Spfa_A(){
int i,j,k;
pa.push(s);
f[s]=1;
dis[s]=0;
while (!pa.empty()){
k=pa.front();
pa.pop();
for (j=1;j<=n;j++){
if (dis[j]>dis[k]+a[k][j]){
dis[j]=dis[k]+a[k][j];
if (!f[j]){
f[j]=1;
pa.push(j);
}
}
}
f[k]=0;
}
if (dis[e]==INF) puts("-1");
else
printf("%d\n",dis[e]);
}
void Spfa_B(){
int i,j,k;
ap.push_back(s);
f[s]=1;
dis[s]=0;
while (!ap.empty()){
k=ap.front();
ap.pop_front();
for (j=1;j<=n;j++){
if (dis[j]>dis[k]+a[k][j]){
dis[j]=dis[k]+a[k][j];
if (!f[j]){
f[j]=1;
if (!ap.empty()){
if (dis[j]<dis[ap.front()]) ap.push_front(j);
else
ap.push_back(j);
}
else
ap.push_back(j);
}
}
}
f[k]=0;
}
if (dis[e]==INF) puts("-1");
else
printf("%d\n",dis[e]);
}
int main(){
readin();
//Floyd(); // O(v^3) 16 ms
//Dijkstra_A(); // O(v*e) 0 ms
//Dijkstra_B(); // O((v+e)log e) 0 ms
//BellmanFord(); // O(v*e) 0 ms
//Spfa_A(); // O(ke) 16 ms
//Spfa_B(); // O(ke) 0 ms
}