营救

洛谷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;
}
原文地址:https://www.cnblogs.com/war1111/p/7340035.html