poj - 3268 Silver Cow Party (求给定两点之间的最短路)

http://poj.org/problem?id=3268

每头牛都要去标号为X的农场参加一个party,农场总共有N个(标号为1-n),总共有M单向路联通,每头牛参加完party之后需要返回自己的农场,但是他们都想选一条最近的路,并且由于路是单向的,去的路和来的路选择可能不一样,问来去时间之和最大是多少?

这题等于给定了起点和终点,那么求出(d[x][i]+d[i][x])最大的那个即可。

开始错了几次,太不小心了,就是最后求最大值的时候,用了一个临时变量没置0,所以可能会导致错误。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <queue>
 7 #include <set>
 8 #include <map>
 9 #include <string>
10 #include <cmath>
11 #include <cstdlib>
12 #include <ctime>
13 using namespace std;
14 const int maxn= 1010;
15 const int INF = 1<<29;
16 struct edge{
17     int to,cost;
18     edge(){}
19     edge(int x,int y) {
20         to=x;
21         cost=y;
22     }
23 };
24 typedef pair<int,int>P;
25 
26 int N,M,X;
27 vector<edge>G[maxn];
28 int d[maxn];
29 
30 int dijkstra(int s,int t) {
31     priority_queue<P,vector<P>,greater<P> >que;
32     for(int i=0;i<=N;i++) d[i]=INF;
33     d[s]=0;
34     que.push(P(0,s));
35 
36     while(!que.empty()) {
37         P p=que.top(); que.pop();
38         int v=p.second;
39         if(v==t) return d[t];
40         if(d[v]<p.first) continue;
41         for(int i=0;i<G[v].size();i++) {
42             edge e=G[v][i];
43             if(d[e.to]>d[v]+e.cost) {
44                 d[e.to]=d[v]+e.cost;
45                 que.push(P(d[e.to],e.to));
46             }
47         }
48     }
49 }
50 
51 int main()
52 {
53     //freopen("a.txt","r",stdin);
54     //freopen("b.txt","w",stdout);
55     int a,b,c;
56     while(~scanf("%d%d%d",&N,&M,&X)) {
57         for(int i=0;i<M;i++) {
58             scanf("%d%d%d",&a,&b,&c);
59             G[a].push_back(edge(b,c));
60         }
61         int sum=0;
62         for(int i=1;i<=N;i++) {
63             sum=max(sum,dijkstra(i,X)+dijkstra(X,i));
64         }
65         printf("%d\n",sum);
66     }
67     return 0;
68 }

 还有一种方法,首先求出点X到各个点i的最短路径,这就是奶牛返回的最短距离,然后把路径反向,在求点X到各个点i的最短距离,就是每个点到点X的最短距离。

 最后把两个距离相交即可。

 不过对于反向,不是很明白。

 时间直接从600多ms降到60多ms。

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <queue>
 7 #include <set>
 8 #include <map>
 9 #include <string>
10 #include <cmath>
11 #include <cstdlib>
12 #include <ctime>
13 using namespace std;
14 const int maxn= 1010;
15 const int INF = 1<<29;
16 struct edge{
17     int to,cost;
18     edge(){}
19     edge(int x,int y) {
20         to=x;
21         cost=y;
22     }
23 };
24 typedef pair<int,int>P;
25 
26 int N,M,X;
27 vector<edge>G[maxn],RG[maxn];
28 int d[maxn],rd[maxn];
29 
30 void dijkstra(int s) {
31     priority_queue<P,vector<P>,greater<P> >que;
32     for(int i=0;i<=N;i++) d[i]=INF;
33     d[s]=0;
34     que.push(P(0,s));
35 
36     while(!que.empty()) {
37         P p=que.top(); que.pop();
38         int v=p.second;
39         if(d[v]<p.first) continue;
40         for(int i=0;i<G[v].size();i++) {
41             edge e=G[v][i];
42             if(d[e.to]>d[v]+e.cost) {
43                 d[e.to]=d[v]+e.cost;
44                 que.push(P(d[e.to],e.to));
45             }
46         }
47     }
48 }
49 
50 int main()
51 {
52     //freopen("a.txt","r",stdin);
53     //freopen("b.txt","w",stdout);
54     int a,b,c;
55     scanf("%d%d%d",&N,&M,&X);
56         for(int i=0;i<M;i++) {
57             scanf("%d%d%d",&a,&b,&c);
58             G[a].push_back(edge(b,c));
59             RG[b].push_back(edge(a,c)); //存储 反向边
60         }
61         dijkstra(X);   //第一次 dijkstra 是求X到各个点的距离
62         //for(int i=1;i<=N;i++) printf("%d\n",d[i]);
63         for(int i=1;i<=N;i++) G[i]=RG[i];  //然后  把反向存储的边赋值给 G
64       //  for(int i=1;i<=N;i++) {
65           //  for(int j=0;j<G[i].size();j++)
66               //  cout<<G[i][j].to<<" "<<G[i][j].cost<<endl;
67        //}
68         memcpy(rd,d,sizeof(d));  //把第一次的 最短距离  保存
69 
70         dijkstra(X);  //反向的 dijkstra 求出每个点到X的最短距离
71         //for(int i=1;i<=N;i++) printf("%d\n",d[i]);
72         int sum=0;   //枚举最大和 
73         for(int i=1;i<=N;i++) {
74             sum=max(sum,d[i]+rd[i]);
75         }
76         printf("%d\n",sum);
77     return 0;
78 }

 

posted @ 2015-05-14 14:58  NowAndForever  阅读(309)  评论(0编辑  收藏  举报