• luoguP1462通往奥格瑞玛的道路(二分答案+spfa)


    题意

    给出n个点m条边的无向图。

    每条边有两个权值a,b;

    问在保证从1到n的路径a权值和小于x时,路径上b权值最大值最小为多少。

    (n≤10000,m≤50000,x≤1000000000)

    题解

    二分x,然后跑最短路判断。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 struct hhh{
      9     int nxt,to,w;
     10 }c[100001];
     11 queue<int> q;
     12 #pragma GCC optimize(2)
     13 /*inline void write(int x)
     14 {
     15      if(x<0) putchar('-'),x=-x;
     16      if(x>9) write(x/10);
     17      putchar(x%10+'0');
     18 }*/
     19 int cnt,book[60000],ans,maxx,l,r,head[60000],dis[60000],n,m,b,w[60000],u,v,k;
     20 bool flag;
     21 inline void add(register int u,register int v,register int w){
     22     cnt++;
     23     c[cnt].w=w;
     24     c[cnt].to=v;
     25     c[cnt].nxt=head[u];
     26     head[u]=cnt;
     27 }
     28 inline void spfa(register int ma){
     29     while(!q.empty()){
     30         register int u=q.front();
     31         q.pop();
     32         book[u]=0;
     33         for(register int i=head[u];i;i=c[i].nxt){
     34             register int v=c[i].to;
     35             if(!book[v]&&w[v]<=ma&&dis[v]>dis[u]+c[i].w&&dis[u]+c[i].w<=b){
     36                 dis[v]=dis[u]+c[i].w;
     37                 book[v]=1;
     38                 q.push(v);
     39                 if(v==1){
     40                     while(!q.empty())q.pop();
     41                     flag=true;
     42                     return;
     43                 }
     44             }
     45         }
     46     }
     47 }
     48 /*inline int read()
     49 {
     50      register int q=0;
     51     register int f=1;
     52     char ch=getchar();
     53     while(ch<'0'||ch>'9')
     54     {
     55         if(ch=='-') f=-1;
     56         ch=getchar();
     57     }
     58     while(!(ch<'0'||ch>'9'))
     59     {
     60         q=q*10+ch-'0';
     61         ch=getchar();
     62     }
     63     return q*f;
     64 }*/
     65 inline int read()
     66 {
     67     register int X=0,w=0; 
     68     char ch=0;
     69     while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
     70     while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
     71     return w?-X:X;
     72 }
     73 
     74 int main(){
     75     n=read();m=read();b=read();
     76     for(register int i=1;i<=n;i++){
     77         w[i]=read();
     78         maxx=max(maxx,w[i]);
     79     }
     80     for(register int i=1;i<=m;i++){
     81         u=read(),v=read(),k=read();
     82         if(u==v)continue;
     83         add(u,v,k);
     84         add(v,u,k);
     85     }
     86     for(register int i=1;i<n;i++){
     87             dis[i]=1100000010;
     88     }
     89     q.push(n);
     90     book[n]=1;
     91     flag=false;
     92     spfa(1000000001);
     93     if(!flag){
     94         printf("AFK");
     95         return 0;
     96     }
     97     l=max(w[1],w[n]);
     98     r=maxx+1;
     99     while(l<=r){
    100         for(register int i=1;i<n;i++){
    101             dis[i]=1100000010;
    102             book[i]=0;
    103         }
    104         flag=false;
    105         int mid=(l+r)/2;
    106         q.push(n);
    107         book[n]=1;
    108         spfa(mid);
    109         if(flag)r=mid-1;
    110         else l=mid+1;
    111         ans=mid;
    112         
    113     }
    114     printf("%d",l);
    115     return 0;
    116 }
    View Code
  • 相关阅读:
    CentOS6.8下安装Docker
    xshell连接Linux(centos6.8)失败的解决方法
    Windows Server定时执行bat
    [译]看漫画学Flux
    LeetCode题型分类及索引
    LeetCode & Q38-Count and Say-Easy
    LeetCode & Q20-Valid Parentheses-Easy
    LeetCode & Q14-Longest Common Prefix-Easy
    LeetCode & Q13-Roman to Integer-Easy
    LeetCode & Q28-Implement strStr-Easy
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9416532.html
Copyright © 2020-2023  润新知