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 }
邻接表:
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 }