poj 3268 Silver Cow Party

/* Name: poj 3268 Silver Cow Party Author: UnimenSun Date: 24/05/2011 23:08 Description: 变形的最短路径 */ /* 解题报告:变形的最短路径 分析:以样例输入为例: 1、先求出各点到2点的最短路径放到数组dis2中 2、再求出2点到各点的最短路径放到数组dis1中 3、求出max(dis1 + dis2),即为所求 关键是第1步怎样求各点到2点的最短路径,用Floyd由于数据量太大会超时,用SPFA、Dijkistra会多次反复的用该算法也会 造成超时,其实只到图中的有向边反转,反转后求2点到各点的最短距离,就相当于求各点到2点的距离 */ //代码一:SPFA算法 #include <iostream> #include <queue> using namespace std; const int MAXN = 2100000; int g[1010][1010]; int n, m, x; int dis1[1010], dis2[1010]; void spfa(int *dis) { int i; for(i=1; i<=n; ++i) dis[i] = MAXN; queue<int> que; que.push(x); dis[x] = 0; while(!que.empty()) { int x = que.front(); que.pop(); for(i=1; i<=n; ++i) { if(g[x][i]!=MAXN && dis[i]>dis[x]+g[x][i]) { dis[i] = dis[x] + g[x][i]; que.push(i); } } } } //有向边转置,其实就是矩阵转置 void Traverse() { int i, j; for(i=1; i<=n; ++i) { for(j=1; j<=i; ++j) { int temp = g[i][j]; g[i][j] = g[j][i]; g[j][i] = temp; } } } int main() { int i, j; while(cin>>n>>m>>x) { //读数据并建图 for(i=1; i<=n; ++i) for(j=1; j<=n; ++j) if(i == j) g[i][j] = 0; else g[i][j] = MAXN; while(m--) { int a, b, t; cin>>a>>b>>t; g[a][b] = t; } spfa(dis1); Traverse(); spfa(dis2); int nMax = 0; for(i=1; i<=n; ++i) { if(i != x) { if(nMax<dis1[i]+dis2[i] && dis1[i]+dis2[i]<MAXN) nMax = dis1[i] + dis2[i]; } } cout<<nMax<<endl; } return 0; } //代码二:Dijkistra求单源最短路径 #include <iostream> #include <cstring> using namespace std; const int MAXN = 2100000; int g[1010][1010]; int n, m, x; int dis1[1010], dis2[1010]; void Dijkistra(int *dis) { int i, j; int visited[1010]; memset(visited, 0, sizeof(visited)); for(i=1; i<=n; ++i) { dis[i] = g[x][i]; visited[i] = 0; } dis[x] = 0; visited[x] = 1; for(i=1; i<n; ++i) { int index=0; int nMin = MAXN; for(j=1; j<=n; ++j) { if(!visited[j] && nMin>dis[j]) { index = j; nMin = dis[j]; } } visited[index] = 1; for(j=1; j<=n; ++j) { if(!visited[j] && g[index][j]!=MAXN && dis[j]>dis[index]+g[index][j]) { dis[j]=dis[index]+g[index][j]; } } } } //有向边转置,其实就是矩阵转置 void Traverse() { int i, j; for(i=1; i<=n; ++i) { for(j=1; j<=i; ++j) { int temp = g[i][j]; g[i][j] = g[j][i]; g[j][i] = temp; } } } int main() { int i, j; while(cin>>n>>m>>x) { //读数据并建图 for(i=1; i<=n; ++i) for(j=1; j<=n; ++j) if(i == j) g[i][j] = 0; else g[i][j] = MAXN; while(m--) { int a, b, t; cin>>a>>b>>t; g[a][b] = t; } Dijkistra(dis1); Traverse(); Dijkistra(dis2); int nMax = 0; for(i=1; i<=n; ++i) { if(i != x) { if(nMax<dis1[i]+dis2[i] && dis1[i]+dis2[i]<MAXN) nMax = dis1[i] + dis2[i]; } } cout<<nMax<<endl; } return 0; }

你可能感兴趣的:(算法,Date)