poj 3268 Silver Cow Party

本文解析了POJ 3268题目的解决方案,通过使用迪杰斯特拉算法并结合特定技巧解决最大路径问题。介绍了算法的具体实现及代码细节。

Silver Cow Party

题目链接:http://poj.org/problem?id=3268


题目大意:在所有的牛场中选一个,其他牛场的牛都会走个来会,路径是单向的,在所有的来回中求个最大的。数据是1000,如果用弗洛伊德O(n^3)h会超时;

所以这里用迪杰斯特拉,但是还必须用一个小技巧,题目要求都与X农场有关,到X和从X出发。所以可以在函数里动手脚,也可以在map里面做文章。


代码如下:

#include<iostream>  
#include<cstdio>  
#include<cstring>  
using namespace std;  
#define INF 0x3f3f3f3; 
int map[1005][1005],dis[1005],visited[1005];  
int xx[1005],nn[1005];
int map2[1005][1005];

void Dj(int n,int x)  
{  
    int p;  
    for(int i=1;i<=n;i++)  
    {  
        dis[i]=map[x][i];  
        visited[i]=0;
    }
    visited[x]=1;
    for(int i=1;i<=n;i++)  
    {  
        int min=INF;
        for(int j=1;j<=n;j++)
        {  
            if(!visited[j] && dis[j]<min)       
            {  
                p=j;  
                min=dis[j];  
            }  
        }  
        visited[p]=1;     
        for(int j=1;j<=n;j++)  
        {  
            if(!visited[j] && dis[p]+map[p][j]<dis[j])      
            {  
                    dis[j]=dis[p]+map[p][j];
            }  
        }  
    }  
}  
  
int main()  
{  
    int n,m,r;
    int x,y,d;
    while(~scanf("%d%d%d",&n,&m,&r))
    {  
        for(int i=1;i<=n;i++) 
            for(int j=1;j<=n;j++) 
                map[i][j]=map2[i][j]=INF; 
        for(int i=1;i<=m;i++) 
        {  
            scanf("%d%d%d",&x,&y,&d);  
            map[x][y]=d;
            map2[y][x]=d;
        }
        
       	Dj(n,r);
       	for(int j=1;j<=n;j++)
        {
       		xx[j]=dis[j];
		}
		for(int i=1;i<=n;i++) 
            for(int j=1;j<=n;j++) 
                map[i][j]=map2[i][j];
		Dj(n,r);
       	for(int j=1;j<=n;j++)
        {
       		nn[j]=dis[j];
		}
		int MAX=-1;
		for(int i=1;i<=n;i++)
		{
			if(i!=r)
			{
				if(nn[i]+xx[i]>MAX)
					MAX=nn[i]+xx[i];
			}
		}
        printf("%d\n",MAX);
    }
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值