zoukankan      html  css  js  c++  java
  • 营救

    洛谷P1396 营救

    多种解法:

    1.spfa,只是松弛操作时更新的是路径上最大值的最小值;(最慢。。24ms

    #include<bits/stdc++.h>
    #define inf 0x7fffffff
    using namespace std;
    struct node
    {
        int n,v;
        node *next;
    }*e[20001];
    
    int n,m,s,t;
    
    void Cin(int &x)
    {
        char c=getchar();x=0;
        while(c>'9'||c<'0')c=getchar();
        while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
    }
    
    int d[10001];
    
    queue<int>q;
    
    int main()
    {
        
        Cin(n),Cin(m),Cin(s),Cin(t);
        node *p;
        node *Q;
        int x;
        for(int i=1;i<=m;i++)
        {
            p=new node();
            Q=new node();
            Cin(x),Cin(p->n),Cin(p->v);
            Q->n=x;
            Q->v=p->v;
            
            if(e[p->n]==NULL)
            {
                e[p->n]=Q;
            }
            else
            {
                Q->next=e[p->n]->next;
                e[p->n]->next=Q;
            }
            
            if(e[x]==NULL)
            {
                e[x]=p;
            }
            else
            {
                p->next=e[x]->next;
                e[x]->next=p;
            }
        }
        for(int i=1;i<=n;i++)
        d[i]=inf;
        d[s]=0;
        q.push(s);
        while(!q.empty())
        {
            p=e[q.front()];
            while(p!=NULL)
            {
                if(max(d[q.front()],p->v)<d[p->n])
                {
                    d[p->n]=max(d[q.front()],p->v);
                    q.push(p->n);
                }
                p=p->next;
            }
            q.pop();
        }
        cout<<d[t];
        return 0;
    }

    2.Kruskal 从小到大加边,直到getfather(s)==getfather(t),然后输出当前边权;(最快。。4ms

    #include<bits/stdc++.h>
    using namespace std;
    
    struct kruskal
    {
        int l,r,t;
        bool operator<(const kruskal&a)const
        {
            return t<a.t;
        }
    }e[20001];
    
    int dad[10001];
    int n,m;
    
    void Cin(int &x)
    {
        char c=getchar();x=0;
        while(c>'9'||c<'0')c=getchar();
        while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
    }
    
    int getfather(int x)
    {
        if(dad[x]==x)
        return x;
        dad[x]=getfather(dad[x]);
        return dad[x];
    }
    
    int s,T;
    
    int main()
    {
        Cin(n),Cin(m),Cin(s),Cin(T);
        for(int i=1;i<=m;i++)
        {
            Cin(e[i].l),Cin(e[i].r),Cin(e[i].t);
        }
        sort(e+1,e+m+1);
        
        for(int i=1;i<=n;i++)
        dad[i]=i;
        int cnt=0;
        int tt=0;
        for(int i=1;i<=m;i++)
        {
            if(getfather(e[i].l)!=getfather(e[i].r))
            {
                dad[getfather(e[i].l)]=e[i].r;
                if(getfather(s)==getfather(T))
                {
                    cout<<e[i].t;
                    return 0;
                }
            }
            
        }
        return 0;
    }

    3.Bfs+二分答案,二分出来mid,然后用边权小于mid的跑bfs,直到找到ti,然后r=mid

    否则l=mid+1;

    #include<bits/stdc++.h>
    using namespace std;
    
    struct node
    {
        int n,v;
        node *next;
    }*e[20001];
    
    bool wnt[10001];
    int n,m;
    
    void Cin(int &x)
    {
        char c=getchar();x=0;
        while(c>'9'||c<'0')c=getchar();
        while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
    }
    
    int s,t;
    int Max;
    queue<int>q;
    
    bool bfs(int mid)
    {
        q.push(s);
        wnt[s]=true;
        node *p;
        while(!q.empty())
        {
            p=e[q.front()];
            while(p!=NULL)
            {
                if(p->v<=mid&&wnt[p->n]==false)
                {
                    if(p->n==t)
                {
                       return true;
                }
                else
                {
                    q.push(p->n);
                    wnt[p->n]=true;
                }
                }
                p=p->next;
            }
            q.pop();
        }
        return false;
    }
    
    int main()
    {
        Cin(n),Cin(m),Cin(s),Cin(t);
        
        node *p;
        node *P;
        int x;
        
        for(int i=1;i<=m;i++)
        {
            p=new node();
            P=new node();
            Cin(x),Cin(p->n),Cin(p->v);
            Max=max(Max,p->v);
            P->v=p->v;
            P->n=x;
            if(e[x]==NULL)
            {
                e[x]=p;
            }
            else
            {
                p->next=e[x]->next;
                e[x]->next=p;
            }
            if(e[p->n]==NULL)
            {
                e[p->n]=P;
            }
            else
            {
                P->next=e[p->n]->next;
                e[p->n]->next=P;
            }
        }
        
        int l=0,r=Max,mid;
        
        while(l<r)
        {
            mid=(l+r)/2;
            if(bfs(mid))
            {
                r=mid;
                while(!q.empty())
                 q.pop();
                memset(wnt,false,sizeof(wnt));
            }
            else
            {
                l=mid+1;
                while(!q.empty())
                q.pop();
                memset(wnt,false,sizeof(wnt));
            }
        }
        cout<<l;
        return 0;
    }
  • 相关阅读:
    四个好看的CSS样式表格
    POJ 2255 Tree Recovery
    黑马程序猿_2014 7月 我使用多线程体验
    Dos命令将合并两个文本文件的内容
    栈和堆之间的差(他转身无数的文章)
    【Espruino】NO.12 加速度计演示
    MySQL进口.sql文件和常用命令
    typedef和define具体的具体差异
    muduo网络图书馆评测
    Web采矿技术
  • 原文地址:https://www.cnblogs.com/war1111/p/7340035.html
Copyright © 2011-2022 走看看