Silver Cow Party
題目鏈接:http://poj.org/problem?id=3268
題目大意:給出n個點和m條邊,接着是m條邊,代表從牛a到牛b需要花費c時間,現在所有牛要到牛x那裏去參加聚會,並且所有牛參加聚會後還要回來,給你牛x,除了牛x之外的牛,他們都有一個參加聚會並且回來的最短時間,從這些最短時間裏找出一個最大值輸出
解題思路:最短路徑只需要從x到i的最短路徑代表他們返回的最短路徑,然後將所有邊反過來,再從x到i的最短路徑代表他們來參加聚會的最短路徑,這樣對應相加找出一個最大值就可以了,當然其實不需要將所有邊反過來,只需要將map的行和列對換一下就可以了,數據比較大,所以floyd超時,用dijkstra比較好點
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
bool book1[1222],book2[1222];
int dis1[1222],dis2[1222];
int inf=0x3f3f3f3f,num;
int maps[1222][1222],n,x;
void Dijstr(int s,int e)
{
int u1,u2,i;
memset(book1,false,sizeof(book1));
memset(book2,false,sizeof(book2));
for(i=1;i<=n;i++)
{
dis1[i]=maps[x][i]; //x到每個點的距離
dis2[i]=maps[i][x]; //轉置矩陣交換行列將去的變成回來的路,就變成其餘農場到x的距離。
}
book1[x]=true;
book2[x]=true;
for(i=1;i<n;i++)
{
int mi1=inf,mi2=inf;
for(int j=1;j<=n;j++)
{
if(mi1>dis1[j]&&!book1[j])
{
mi1=dis1[j];
u1=j;
}
if(mi2>dis2[j]&&!book2[j])
{
mi2=dis2[j];
u2=j;
}
}
book1[u1]=true;
book2[u2]=true;
for(int v=1;v<=n;v++)
{
if(!book1[v]&&dis1[v]>dis1[u1]+maps[u1][v])
{
dis1[v]=dis1[u1]+maps[u1][v];
}
if(!book2[v]&&dis2[v]>dis2[u2]+maps[v][u2])
{
dis2[v]=dis2[u2]+maps[v][u2];
}
}
}
}
int main()
{
int m,i;
int u,v,w;
scanf("%d%d%d",&n,&m,&x);
memset(maps,inf,sizeof(maps));
for(i=0;i<=n;i++) maps[i][i]=0;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
maps[u][v]=w;
}
int ma=-1,sum;
Dijstr(n,x); // 每組數據只需要進行一次Dijstr就可以。
for(i=1;i<=n;i++)
{
if(i==x) continue;
sum=dis1[i]+dis2[i];//dis1存儲的x到其餘點的距離,dis2存儲的是其餘點到x的距離。
ma=max(sum,ma); // 找到一個最大值存儲。
}
printf("%d\n",ma);
return 0;
}