习题日常第九练

1最短路(题目链接

最短路问题的第二练,这个题用的是贝尔曼—福德算法的队列优化。具体代码如下。

#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#define ll long long int
const int mod=1e9+7;
using namespace std;
ll a[200010],b[200010],ap=0,dis[200010];
struct node
{
    ll l,r,v,next;
}t[200010];
void add(ll x,ll y,ll z)
{
    t[++ap].l=x;
    t[ap].r=y;
    t[ap].v=z;
    t[ap].next=a[x];
    a[x]=ap;
}
queue<ll>p;
int main()
{
    ios::sync_with_stdio(false);
    ll n,m,s,i,j,k;
    cin>>n>>m;
        for(i=0;i<=m;i++)
    {
        t[i].next=-1;
    }
    for(i=1;i<=n;i++)
        a[i]=-1;
    for(i=0;i<m;i++)
    {
        ll x,y,z;
        cin>>x>>y>>z;
        add(x,y,z);
    }
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    dis[0]=0;
    memset(b,0,sizeof(b));
    p.push(1);
    while(!p.empty())
    {
        ll x=p.front();
        p.pop();
        b[x]=1;
        for(i=a[x];i!=-1;i=t[i].next)
        {
            if(dis[t[i].r]>dis[x]+t[i].v)
            {
                dis[t[i].r]=dis[x]+t[i].v;
                if(b[t[i].r]!=1)
                {
                    p.push(t[i].r);
                    b[t[i].r]=1;
                }
            }
        }
    }
    for(i=2;i<=n;i++)
        cout<<dis[i]<<endl;
  return 0;
}

2旅行(题目链接

这个题用的还是迪杰斯特拉算法的优先队列优化。把每一个点作为中转点,算一下其它每一个点距离它的最小距离,然后挑俩个最大的距离加起来即可,每次维护这个最大值。具体代码如下。

#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#define ll long long int
const int mod=1e9+7;
using namespace std;
ll a[200010],b[200010],ap=0,dis[200010],n,m;
struct node
{
    ll l,r,v,next;
}t[200010];
void add(ll x,ll y,ll z)
{
    t[++ap].l=x;
    t[ap].r=y;
    t[ap].v=z;
    t[ap].next=a[x];
    a[x]=ap;
}
bool cmp(int z,int o)
{
    return z>o;
}
priority_queue<pair<ll,ll> >p;
ll ans(ll s)
{
    ll i,j,k;
    for(i=0;i<=n;i++)
        dis[i]=1e10;
    dis[s]=0;
    memset(b,0,sizeof(b));
    p.push(make_pair(0,s));
    while(!p.empty())
    {
        ll x=p.top().second;
        p.pop();
        if(b[x]==1)
            continue;
            b[x]=1;
        for(i=a[x];i!=-1;i=t[i].next)
        {
            if(dis[t[i].r]>dis[x]+t[i].v)
            {
                dis[t[i].r]=dis[x]+t[i].v;
                p.push(make_pair(-dis[t[i].r],t[i].r));
            }
        }
    }
    ll ano=-1,num=0;
   sort(dis+1,dis+n+1,cmp);
   for(i=1;i<n-1;i++)
   {
       if(dis[i]!=1e10&&dis[i+1]!=1e10)
        return dis[i]+dis[i+1];
   }
   return -1;
}
int main()
{
    ios::sync_with_stdio(false);
    ll t,s,i,j,k;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        ap=0;
        for(i=1;i<=2*n;i++)
            a[i]=-1;
        for(i=0;i<m;i++)
        {
            ll x,y,z;
            cin>>x>>y>>z;
            add(x,y,z);
            add(y,x,z);
        }
         ll pa=-1;
     for(i=1;i<=n;i++)
     {
         pa=max(pa,ans(i));
     }
     cout<<pa<<endl;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值