最短路练习2

POJ3268 Silver Cow Party

双向建边
注意题意就是去的路和返回来的路可能不是同一条,因为a->b和b->a的路径长度不一样
就是计算两次dij,在找那个最大的就好了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#include<iostream>
#include<iomanip>
const int inf=0x3f3f3f3f;
const int N=1050;
using namespace std;
int n,m,x;
int tu[N][N];
int dis[N];
int vis[N];


void dij(int s)
{

    for(int i=0;i<n;i++)
    {
        dis[i]=tu[s][i];
    }

    dis[s]=0;
    int minn=inf;
    int v;
    while(true)
    {
        v=-1;
        minn=inf;
        for(int i=0;i<n;i++)
        {
            if(!vis[i]&&minn>dis[i])
            {
                minn=dis[i];
                v=i;
            }
        }
        if(v==-1)break;
        vis[v]=1;
        for(int i=0;i<n;i++)
        {
            if(!vis[i]&&dis[i]>dis[v]+tu[v][i])
            {
                dis[i]=dis[v]+tu[v][i];
            }
        }
    }
}


int main()
{
    cin>>n>>m>>x;
    x--;
    int ans[N];
    memset(ans,0,sizeof(ans));
        int a,b,c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            if(i==j)
                tu[i][j]=0;
            else
            tu[i][j]=inf;
    for(int i=0;i<m;i++)
    {
        cin>>a>>b>>c;
        a--;b--;
        tu[a][b]=c;
    }
    memset(vis,0,sizeof(vis));
    dij(x);
    int tmp;
    for(int i=0;i<n;i++)
        {
            ans[i]=dis[i];
        }
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
    {
        tmp = tu[i][j];
        tu[i][j]=tu[j][i];
        tu[j][i]=tmp;
    }
    memset(vis,0,sizeof(vis));
    dij(x);
    int maxx=-inf;
    for(int i=0;i<n;i++)
        {
            ans[i]+=dis[i];
            maxx=max(maxx,ans[i]);
    }
    cout<<maxx<<endl;


    return 0;
}

POJ1860

bellman-ford算法水题
比较easy
就是判断有没有负环的题目,这个是判断有没有正环,建议先掌握bellman算法在看这个题,就比较好做了,bellman是常用来判断是否有负环的

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#include<iostream>
#include<iomanip>
const int inf=0x3f3f3f3f;
const int N=1050;
using namespace std;
int n,m,x;

double dis[N];
int tol=0;
double hl[N];
double yj[N];
int di[N];
int to[N];
void belleman_ford(int x,double mmm)
{
    for(int i=0;i<n;i++) dis[i]=0;
    dis[x]=mmm;
    int d1,d2;
    for(int i=1;i<n;i++)
    {   int fl=1;
        for(int j=0;j<tol;j++)
        {
            d1=di[j];d2=to[j];
            if(dis[d2]<(dis[d1]-yj[j])*hl[j])
            {
                dis[d2]=(dis[d1]-yj[j])*hl[j];
                fl=0;
            }
        }
        if(fl)break;
    }
    int fl=1;
    for(int i=0;i<tol;i++)
    {d1=di[i];d2=to[i];
        if(dis[d2]<(dis[d1]-yj[i])*hl[i])
        {
            printf("YES\n");
            fl=0;break;
        }
    }
    if(fl)
    cout<<"NO\n"<<endl;
}

int main()
{
        int s;
    double sum;
    cin>>n>>m>>s>>sum;
    s--;
    int a,b;
    double c,d,e,f;

    for(int i=0;i<m;i++)
    {
        cin>>a>>b>>c>>d>>e>>f;
        a--;
        b--;
        di[tol]=a;
        to[tol]=b;
        hl[tol]=c;
        yj[tol]=d;
        tol++;
        di[tol]=b;
        to[tol]=a;
        hl[tol]=e;
        yj[tol]=f;
        tol++;

    }
    belleman_ford(s,sum);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值