csuoj--1307

dijkstra算法的一种变形吧

题目要求的是最长路的最小值,所以用二分枚举最长路,

注意要改变一下松弛的条件:只对满足权值小于我们枚举的最长路的值得边进行松弛。


代码如下:


#include<iostream>
#include<cstring>
#include<cstdio> 
#include<queue>
#include<algorithm>
using namespace std;

#define INF 1<<30
#define Max 55550
int u[Max],v[Max],w[Max],d[Max];
int first[Max],next[Max],e,n,m;

typedef pair<int,int>pii;
priority_queue<pii,vector<pii>,greater<pii> >q;

void dijkstra(int s,int mid)
{
     int i,j,k;
     for(i=1;i<=n;i++)
         d[i]=INF;
     d[s]=0;
     q.push(make_pair(d[s],s));
     while(!q.empty())
     {
          while(!q.empty()&&q.top().first>d[q.top().second])
                q.pop();
          if(q.empty())
              return ;
          pii u=q.top();
          q.pop();
          int x=u.second;
          for(int e=first[x];e!=-1;e=next[e])
              if(w[e]<=mid)
                 if(d[v[e]]>d[x]+w[e])
                 {
                      d[v[e]]=d[x]+w[e];
                      q.push(make_pair(d[v[e]],v[e]));
                 }
     } 
}

void Init()
{
     memset(first,-1,sizeof(first));
     e=0;
}

void add_e(int a,int b,int c)
{
     u[e]=a;v[e]=b;w[e]=c;
     next[e]=first[a];
     first[a]=e++;
} 

int main()
{
    int A,B,i,j;
    while(scanf("%d%d%d%d",&n,&m,&A,&B)!=EOF)
    {
          Init();
          for(i=0;i<m;i++)
          {
               int k1,k2,cost;
               scanf("%d%d%d",&k1,&k2,&cost);
               add_e(k1,k2,cost);
               add_e(k2,k1,cost);
          } 
          int l=0,r=10000,ans;
          while(l<=r)
          {
              int mid=(l+r)/2;
              dijkstra(A,mid);
              if(d[B]<INF)
                 r=mid-1,ans=d[B];
              else
                 l=mid+1;
          }
          printf("%d\n",ans);
    } 
 return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值