题目链接:
http://poj.org/problem?id=3268
题意:
许多牛到编号为X出开party,每只牛到达X处并且返回自己原先位置所需的最短路径和为L1,L2.......
求其中最大的值:
输入N,M,X,
N表示有N个点
M表示有M条边
X表示目的地的编号
输出:到达编号X并且返回自己原先位置所需的最短路径和 最大的编号
思路:
1.以X编号为起点,求出到达其他各点所需 的最短路径L1
2.求出各点到达编号X的最短路径L2
3.求出(L1+L2)最大值
做法:
1.dijkstra(x,n)//求编号X到达各点的最短距离
2.该图是有向图 所以把所有路径方向取反:原来是1到2 现在变成2到1
3.dijkstra(x,n) //这个时候就相当于求各点到达编号X的最短距离了
样例解析:
4 8 2 1 2 4 1 3 2 1 4 7 2 1 1 2 3 5 3 1 2 3 4 4 4 2 3
共有4个点8条边 目的地编号为2
编号1到达2的最短路径:
1->2 4
返回最短路径:
2->1 1
和为: 5
L1=5
**************
编号3到达2的最短路径:
3->1->2 6
返回最短路径:
2->1->3 3
和为: 9
L3=9
***************
编号4到达2的最短路径:
4->2 3
返回最短路径:
2->1->3->4 7
和为: 10
L4=10
L1,L3,L4中最大的是L4=10所以输出10
/*
题意是:
所有牛用最小时间到达 x处并且返回自己原来的地方
找出 其中用时最长的 并且输出这个时间
思路:
求出 起点 1...n 到达 x的最短距离 a
求出 起点x 到达 1.....n 的最短距离 b
求出 ans=max(a+b,ans);
方法:
1.以x为起点 dijkstra 一次 求出 以x为起点到达 其他处的最短距离
2.把G[i][j] 与G[j][i]值交换
3.以x为起点 dijkstra 一次 求出 其他处到达 x的最短距离
*/
#include<cstdio>
#include<cstring>
#define INF 1000000000
const int N=1001;
int G[N][N];
int sum[N];
int max(int a,int b){return a>b?a:b;}
void dijkstra(int s,int n)
{
int dis[N]={0};
bool vis[N]={0};
int pos=s,i,j,min;
for(int i=1;i<=n;++i)dis[i]=G[pos][i];
// dis[s]=0;
vis[pos]=true;
for(i=1;i<n;++i){
for(j=1,min=INF;j<=n;++j){
if(!vis[j]&&dis[j]<min){
min=dis[j];
pos=j;
}
}
vis[pos]=true;
sum[pos]+=min;
// printf("pos:%d sum[pos]=%d\n",pos,sum[pos]);
for(j=1;j<=n;++j){
if(!vis[j]&&dis[j]>dis[pos]+G[pos][j]){
dis[j]=dis[pos]+G[pos][j];
}
}
}
}
int main()
{
int n,m,x;
int s,e,dist;
while(~scanf("%d %d %d",&n,&m,&x)){
for(int i=0;i<=n;++i)
for(int j=0;j<=n;++j){
G[i][j]=INF;
if(i==j) G[i][i]=0;}
for(int i=0;i<m;++i){
scanf("%d %d %d",&s,&e,&dist);
if(dist<G[s][e])
G[s][e]=dist;
}
memset(sum,0,sizeof(sum));
dijkstra(x,n);
for(int i=0;i<=n;++i)
for(int j=0;j<i;++j){//注意这里的
int tmp=G[i][j];
G[i][j]=G[j][i];
G[j][i]=tmp;
}
dijkstra(x,n);
int ans=-1;
for(int i=1;i<=n;++i)
ans=max(sum[i],ans);
// printf("sum[%d]=%d\n",i,sum[i]);
printf("%d\n",ans);
}
}