POJ-3268-Silver Cow Party

题目要求求出n牛头到一点参加聚会然后返回所需的最长时间

其实就是正向建图后求x点到所有点的最短路径以及建立反向图求x到所有点的最短路径,两次最短路径和的最大值就是所求

用Spfa求2次最短路径即可,具体看代码吧

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int maxn=100100;
const int maxm=1010;
int head[2][maxm],pnt[2][maxn],nxt[2][maxn],cost[2][maxn],dist[2][maxm];
int n,m,x,e,ans;
bool vis[maxm];
queue<int> q;
void AddEdge(int u,int v,int c,int pos)
{
    pnt[pos][e]=v;nxt[pos][e]=head[pos][u];cost[pos][e]=c;head[pos][u]=e++;
}
void Spfa(int st,int pos)
{
    memset(dist[pos],0x7f,sizeof(dist[pos]));
    memset(vis,0,sizeof(vis));
    q.push(st);
    dist[pos][st]=0;
    while(!q.empty())
    {
	int u=q.front();
	vis[u]=0;
	q.pop();
	for(int i=head[pos][u];i!=-1;i=nxt[pos][i])
	{
	    int v=pnt[pos][i];
	    if(dist[pos][v]>dist[pos][u]+cost[pos][i])
	    {
		dist[pos][v]=dist[pos][u]+cost[pos][i];
		if(!vis[v])
		{
		    q.push(v);
		    vis[v]=1;
		}
	    }
	}
    }
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&x)!=EOF)
    {
	memset(head,-1,sizeof(head));
	ans=e=0;
	for(int i=0;i<m;i++)
	{
	    int u,v,c;
	    scanf("%d%d%d",&u,&v,&c);
	    AddEdge(u,v,c,0);
	    AddEdge(v,u,c,1);
	}
	Spfa(x,0);
	Spfa(x,1);
	for(int i=1;i<=n;i++)
	    ans=max(ans,dist[0][i]+dist[1][i]);
	printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(最短路径,SPFA)