畅通工程续
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 14 Accepted Submission(s) : 2
Problem Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
Sample Input
3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
Sample Output
2 -1
简单的dij,不解释。
#include<iostream>
#include<stdio.h>
using namespace std;
#define inf 99999999
int map[205][205],vis[205],dis[205];
int n,m;
void dij(int s,int e)
{
int k=0;
for(int i=0; i<n; i++)
{
dis[i]=map[s][i];
vis[i]=0;
}
vis[s]=1;
for(int i=1; i<n; i++)
{
int max=inf;
for(int j=0; j<n; j++)
{
if(!vis[j]&&dis[j]<max)
{
max=dis[j];
k=j;
}
}
if(k==e) return ;
vis[k]=1;
for(int j=0; j<n; j++)
{
if(!vis[j]&&dis[j]>dis[k]+map[k][j])
dis[j]=dis[k]+map[k][j];
}
}
}
int main()
{
int a,b,v;
int st,end;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
map[i][j]=inf;
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&a,&b,&v);
if(map[a][b]>v)
map[a][b]=map[b][a]=v;
}
scanf("%d%d",&st,&end);
if(st==end)
cout<<"0"<<endl;
else
{
dij(st,end);
if(dis[end]==inf)
cout<<"-1"<<endl;
else
cout<<dis[end]<<endl;
}
}
return 0;
}
/*
3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2
*/
A Walk Through the Forest
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 5 Accepted Submission(s) : 2
Problem Description
Jimmy experiences a lot of stress at work these days, especially since his accident made working difficult. To relax after a hard day, he likes to walk home. To make things even nicer, his office is on one side of a forest, and his house is on the other. A nice walk through the forest, seeing the birds and chipmunks is quite enjoyable.
The forest is beautiful, and Jimmy wants to take a different route everyday. He also wants to get home before dark, so he always takes a path to make progress towards his house. He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. Calculate how many different routes through the forest Jimmy might take.
The forest is beautiful, and Jimmy wants to take a different route everyday. He also wants to get home before dark, so he always takes a path to make progress towards his house. He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. Calculate how many different routes through the forest Jimmy might take.
Input
Input contains several test cases followed by a line containing 0. Jimmy has numbered each intersection or joining of paths starting with 1. His office is numbered 1, and his house is numbered 2. The first line of each test case gives the number of intersections N, 1 < N ≤ 1000, and the number of paths M. The following M lines each contain a pair of intersections a b and an integer distance 1 ≤ d ≤ 1000000 indicating a path of length d between intersection a and a different intersection b. Jimmy may walk a path any direction he chooses. There is at most one path between any pair of intersections.
Output
For each test case, output a single integer indicating the number of different routes through the forest. You may assume that this number does not exceed 2147483647
Sample Input
5 6 1 3 2 1 4 2 3 4 3 1 5 12 4 2 34 5 2 24 7 8 1 3 1 1 4 1 3 7 1 7 4 1 7 5 1 6 7 1 5 2 1 6 2 1 0
Sample Output
2 4
此题为求最短路的条数。网上的一个思想,记忆式搜索。先求出2到各点的最短距离,然后搜索得到结果。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
#define inf 99999999
int map[1005][1005],vis[1005],dis[1005];
vector<int> road[1005];//定义一个容器(向量)
int s[1005];
int n,m;
void dij(int s)
{
int k=1;
for(int i=1; i<=n; i++)
{
dis[i]=map[s][i];
vis[i]=0;
}
vis[s]=1;
for(int i=1; i<n; i++)
{
int max=inf;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]<max)
{
max=dis[j];
k=j;
}
}
vis[k]=1;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]>dis[k]+map[k][j])
dis[j]=dis[k]+map[k][j];
}
}
}
int dfs(int now)
{
if(now==2)return 1;
if(s[now])return s[now];
for(int i=0;i<road[now].size();i++)
{
if(dis[now]>dis[road[now][i]])
s[now]+=dfs(road[now][i]);
}
return s[now];
}
int main()
{
int a,b,v;
int st,end;
while(scanf("%d",&n),n)
{
scanf("%d",&m);
memset(s,0,sizeof(s));
for(int i=0;i<=n;i++)
road[i].clear();
for(int i=0; i<=n; i++)
for(int j=0; j<=n; j++)
if(i==j)
map[i][j]=0;
else
map[i][j]=inf;
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&a,&b,&v);
if(map[a][b]>v)
{
map[a][b]=map[b][a]=v;
road[a].push_back(b);
road[b].push_back(a);
}
}
dij(2);
cout<<dfs(1)<<endl;
}
return 0;
}
/*
5 6
1 3 2
1 4 2
3 4 3
1 5 12
4 2 34
5 2 24
7 8
1 3 1
1 4 1
3 7 1
7 4 1
7 5 1
6 7 1
5 2 1
6 2 1
0
*/