POJ 3268 Silver Cow Party 正反图最短路

题目:click here

题意:

  给出n个点和m条边,接着是m条边,代表从牛a到牛b需要花费c时间,现在所有牛要到牛x那里去参加聚会,并且所有牛参加聚会后还要回来,给你牛x,除了牛x之外的牛,他们都有一个参加聚会并且回来的最短时间,从这些最短时间里找出一个最大值输出。

分析:

  最短路径只需要从x到i的最短路径代表他们返回的最短路径,然后将所有边反过来,再从x到i的最短路径代表他们来参加聚会的最短路径,这样对应相加找出一个最大值就可以了,当然其实不需要将所有边反过来,只需要将map的行和列对换一下就可以了,数据比较大,所以floyd超时,用dijkstra比较好点。

邻接矩阵:~~~不知道这个题为什么邻接矩阵会比邻接表快~~~

 1 #include <iostream>
 2 #include <cstring>
 3 #include <vector>
 4 #include <cstdio>
 5 #include <queue>
 6 #include <algorithm>
 7 
 8 using namespace std;
 9 typedef pair<int,int> P;
10 const int INF = 1e9+7;
11 const int M = 1e3+5;
12 
13 int n, m, x;
14 int f, t, c;
15 int cost[M][M];
16 int costb[M][M];
17 int d[M];
18 int db[M];
19 bool vis[M];
20 
21 void dijkstra( int s, int *dist, int field[M][M] )  {
22     fill( dist, dist+n+1, INF );
23     memset( vis, false, sizeof(vis) );
24     vis[s] = true;
25     dist[s] = 0;
26     int tm = n;
27     while( tm-- )   {
28         int minn = INF, k = s;
29         for( int i=1; i<=n; i++ )   {
30             if( !vis[i] && dist[i] < minn ) {
31                 minn = dist[i];
32                 k = i;
33             }
34         }
35         vis[k] = true;
36         for( int i=1; i<=n; i++ )   {
37             if( !vis[i] && dist[i] > dist[k] + field[k][i] )
38                 dist[i] = dist[k] + field[k][i];
39         }
40     }
41 }
42 
43 void solve()    {
44     int ret = -INF;
45     dijkstra( x, d, cost );     // 正图 和 反图的最短路
46     dijkstra( x, db, costb );
47     for( int i=1; i<=n; i++ )
48         ret = max( ret, d[i]+db[i] );
49     printf("%d\n", ret );
50 }
51 
52 int main()  {
53     while( ~scanf("%d%d%d", &n, &m, &x ) )  {
54         for( int i=0; i<=n; i++ )   {
55             for( int j=0; j<=n; j++ )   {
56                 cost[i][j] = INF;
57                 costb[i][j] = INF;
58             }
59         }
60         for( int i=0; i<m; i++ )    {
61             scanf("%d%d%d", &f, &t, &c );
62             cost[f][t] = c;
63             costb[t][f] = c;
64         }
65         solve();
66     }
67     return 0;
68 }
View Code

邻接表:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <vector>
 4 #include <cstdio>
 5 #include <queue>
 6 #include <algorithm>
 7 
 8 using namespace std;
 9 typedef pair<int,int> P;
10 const int INF = 1e9+7;
11 const int M = 1e3+5;
12 
13 struct edge { int to, cost; };
14 int n, m, x;
15 int f, t, c;
16 int d[M];
17 int db[M];
18 vector<edge> G[M];
19 
20 void dijkstra( int s, int *dist )  {
21     priority_queue< P, vector<P>, greater<P> > que;
22     fill( dist, dist+n+1, INF );
23     dist[s] = 0;
24     que.push( P(0,s) );
25     while( !que.empty() )   {
26         P p = que.top(); que.pop();
27         int v = p.second;
28         if( dist[v] < p.first ) continue;
29         for( int i=0; i<G[v].size(); i++ )  {
30             edge e = G[v][i];
31             if( dist[e.to] > dist[v] + e.cost )   {
32                 dist[e.to] = dist[v] + e.cost;
33                 que.push( P(dist[e.to],e.to) );
34             }
35         }
36     }
37 }
38 
39 void solve()    {
40     dijkstra( x, db );
41     int ret = -INF;
42     for( int i=1; i<=n; i++ )   {
43         dijkstra( i, d );
44             ret = max( ret, d[x]+db[i] );
45     }
46     printf("%d\n", ret );
47 }
48 int main()  {
49     while( ~scanf("%d%d%d", &n, &m, &x ) )  {
50         for( int i=0; i<m; i++ )    {
51             scanf("%d%d%d", &f, &t, &c );
52             G[f].push_back( (edge){t,c} );
53         }
54         solve();
55     }
56     return 0;
57 }
View Code

 

posted @ 2015-08-24 21:39  TaoTaoCome  阅读(176)  评论(0编辑  收藏  举报