【题目链接】
http://poj.org/problem?id=3268
题目意思
有n只牛,编号从1到n,现在k号家开party,所以牛都会去,当这些牛非常懒,他们想尽可能走短的路(去时加回来),现在路是有向路,问路程最远的一只牛的路程
解题思路
每只牛的路程都可以分成去时和回时。可以用spfa或迪杰斯特拉单源点循环跑,找最大的。弗洛伊德会超时。上面这虽然会过但是耗时大,只要把有向边反过来建立反向图这样跑两遍就够了(看了大神vector用法真的6)。
代码部分
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <map>
using namespace std;
#define LL long long
//#define inf 0x3f3f3f3
const int N = 1005;
const int inf = 999999;
int dis[N]; ///存储最短路
int vis[N]; ///记录是否在队列
int t,k,n;
struct node
{
int v,w;
}s;
vector<node>m[N];
void spfa(int s)
{
memset(vis,0,sizeof(vis));
memset(dis,inf,sizeof(dis));
queue<int>q;
q.push(s);
vis[s] = 1;
dis[s] = 0;
while (!q.empty())
{
int t = q.front();
q.pop();
for (int i = 0; i < m[t].size();i++)
{
if (dis[m[t][i].v] > dis[t]+m[t][i].w) ///松弛
{
dis[m[t][i].v] = dis[t]+m[t][i].w;
if (!vis[m[t][i].v]) ///判断是否在队列
{
q.push(m[t][i].v);
vis[m[t][i].v] = 1;
}
}
}
vis[t] = 0;
}
}
int main()
{
int Max = -1;
scanf("%d %d %d",&n,&t,&k);
for(int i =0; i < t;i++)
{
int v,u,w;
scanf("%d %d %d",&u,&v,&w);
s.v = v;
s.w = w;
m[u].push_back(s);
}
for (int i = 1; i <= n; i++)
{
int s=0;
spfa(i);
s += dis[k];
spfa(k);
s += dis[i];
if (Max < s)
Max = s;
}
printf("%d\n",Max);
return 0;
}
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <map>
using namespace std;
#define LL long long
//#define inf 0x3f3f3f3
const int N = 1005;
const int inf = 999999;
int dis[N]; ///存储正向最短路
int fdis[N]; ///存储反向最短路
int vis[N]; ///记录是否在队列
int t,k,n;
struct node
{
int v,w;
}s;
vector<vector<node> >m(N); ///正向图
vector<vector<node> >fm(N); ///反向图
void spfa(int s)
{
memset(vis,0,sizeof(vis));
memset(dis,inf,sizeof(dis));
queue<int>q;
q.push(s);
vis[s] = 1;
dis[s] = 0;
while (!q.empty())
{
int t = q.front();
q.pop();
for (int i = 0; i < m[t].size();i++)
{
if (dis[m[t][i].v] > dis[t]+m[t][i].w) ///松弛
{
dis[m[t][i].v] = dis[t]+m[t][i].w;
if (!vis[m[t][i].v]) ///判断是否在队列
{
q.push(m[t][i].v);
vis[m[t][i].v] = 1;
}
}
}
vis[t] = 0;
}
}
int main()
{
int Max = -1;
scanf("%d %d %d",&n,&t,&k);
for(int i =0; i < t;i++)
{
int v,u,w;
scanf("%d %d %d",&u,&v,&w);
s.v = v;
s.w = w;
m[u].push_back(s);
s.v = u;
fm[v].push_back(s);
}
spfa(k);
memcpy(fdis,dis,sizeof(dis));
m = fm;
spfa(k);
for (int i = 1; i <= n; i++)
{
Max = max(Max,dis[i]+fdis[i]);
}
printf("%d\n",Max);
return 0;
}