186. [USACO Oct08] 牧场旅行 (第三次考试大整理)

186. [USACO Oct08] 牧场旅行

   输入文件:pwalk.in   输出文件:pwalk.out   简单对比
时间限制:1 s   内存限制:128 MB

n个被自然地编号为1..n奶牛(1<=n<=1000)正在同样被方便的编号为1..n的n个牧场中吃草。更加自然而方便的是,第i个奶牛就在第i个牧场中吃草。

其中的一些对牧场被总共的n-1条双向通道的一条连接。奶牛可以通过通道。第i条通道连接的两个牧场是A_i和B_i(1<=A_i<=N;1<=B_i<=N)其长度是L_i(1<=L_i<=10000)。

通道只会连接两个不同的牧场,所以这些通道使得整个牧场构成了一棵树。

奶牛们是好交际的希望能够经常的访问别的奶牛。急切地,它们希望你能通过告诉它们Q(1<=Q<=1000)对牧场的路径来帮助他们安排旅行。(这里将有Q个询问,p1,p2(1<=p1<=n;1<=p1<=n))

问题名称:

pwalk

输入格式:

  • 第1行:两个用空格隔开的整数:n和Q
  • 第2..n行:第i+1行包含三个用空格隔开的整数:A_i,B_i和L_i
  • 第n+1..N+Q行:每行包含两个用空格隔开的整数,代表两个不同的牧场,p1和p2

输入样例(file pwalk.in):

4 2

2 1 2

4 3 2

1 4 3

1 2

3 2

输出格式:

  • 第1..Q行:行i包含第i个询问的答案。

输出样例:

2

7

输出说明:

询问1:牧场1和牧场2的路径长度为2。 询问2:3->4->1->2;总长为7。

思路:

  就是裸的spfa!!!

①90代码(弗洛伊德):
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define M 1005
 5 
 6 using namespace std;
 7 
 8 int map[M][M];
 9 int n,q,x,y,w;
10 
11 int main()
12 {
13     //freopen("pwalk.in","r",stdin);
14     //freopen("pwalk.out","w",stdout);
15     memset(map,10001,sizeof(map));
16     cin>>n>>q;
17     for(int i=1;i<=n-1;i++)
18     {
19         scanf("%d%d%d",&x,&y,&w);
20         map[x][y]=map[y][x]=w;
21     }
22     for(int k=1;k<=n;k++)
23     for(int i=1;i<=n;i++)
24     for(int j=1;j<=n;j++)
25     {
26         if(map[i][j]>map[i][k]+map[k][j])
27         map[i][j]=map[i][k]+map[k][j];
28     }
29     for(int i=1;i<=q;i++)
30     {
31         scanf("%d%d",&x,&y);
32         cout<<map[x][y]<<endl;
33     }
34     //fclose(stdin);
35     //fclose(stdout);
36     return 0;
37 }

②改进后的代码(spfa):

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #define MAXN 1001
 7 #define maxn 0x7fffffff
 8 
 9 using namespace std;
10 
11 struct node
12 {
13     int u;
14     int v;
15     int w;
16     int next;
17 }edge[MAXN];
18 
19 int head[MAXN],dis[MAXN];
20 int n,q,vis[MAXN],num=1;
21 
22 int spfa(int bg,int ed)//如题,裸的spfa 
23 {
24     for(int i=1;i<=n;i++) dis[i]=maxn;
25     memset(vis,0,sizeof(vis));
26     queue<int>q;
27     q.push(bg);
28     dis[bg]=0;
29     vis[bg]=1;
30     while(q.size()!=0)
31     {
32         int p=q.front();
33         q.pop();
34         for(int i=head[p];i!=-1;i=edge[i].next)
35         {
36             int to=edge[i].v;
37             if(dis[to]>dis[p]+edge[i].w)
38             {
39                 dis[to]=dis[p]+edge[i].w;
40                 if(vis[to]==0)
41                 {
42                     q.push(to);
43                     vis[to]=1; //必须要进行标记!!!   
44                 }
45             }
46         }
47     }
48     return dis[ed];
49 }
50 int main()
51 {
52     //freopen("pwalk.in","r",stdin);
53     //freopen("pwalk.out","w",stdout);
54     scanf("%d%d",&n,&q);
55     for(int i=1;i<=n;i++)head[i]=-1;//进行初始化 
56     for(int i=1;i<n;i++)
57     {
58         scanf("%d%d%d",&edge[num].u,&edge[num].v,&edge[num].w);
59         edge[num].next=head[edge[num].u];
60         head[edge[num].u]=num++;
61         edge[num].v=edge[num-1].u;
62         edge[num].u=edge[num-1].v;
63         edge[num].w=edge[num-1].w;
64         edge[num].next=head[edge[num].u];
65         head[edge[num].u]=num++;
66     }
67     for(int i=1;i<=q;i++)//进行输出 
68     {
69         int bg;
70         int ed;
71         scanf("%d%d",&bg,&ed);
72         printf("%d\n",spfa(bg,ed));
73     }
74     return 0;
75 }

 

posted @ 2017-04-18 22:24  夜雨声不烦  阅读(82)  评论(0编辑  收藏  举报