P1396レスキュー(最小スパニングツリー+最短パスレコードパス)

タイトルポータル

アイデアは、nポイントの無向グラフを与え、mエッジを与え、複数のエッジを持っている可能性があることです。sからtまで歩くには、通過する道路の重量の最大値が最小である必要があります。この答えを見つけてください。

アイデア:
重みは可能な限り小さいので、最小全域木を考えるのは簡単です。最初にkruskalを使用して最小スパニングツリーを作成し、エッジの重みと最小値を含むグラフを取得します。次に、ダイクストラがそれを再度実行し、パスと重みを記録し、最後に最大値を維持するためにバックトラックします。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
const int eps=1e-6;
typedef long long ll;
typedef unsigned long long ull;
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
int head[N<<1],nxt[N<<1],to[N<<1],val[N<<1],tot=0,crt=0;
struct node
{
    int x,y,z;
}e[N<<1];
void addedge(int u,int v,int w,int p)
{
    if(p==1)
    {
        e[++tot].x=u;
        e[tot].y=v;
        e[tot].z=w;
    }
    if(p==2)
    {
        nxt[++crt]=head[u];
        to[crt]=v;
        val[crt]=w;
        head[u]=crt;
    }
}
int dis[N],vis[N],pre[N];int n;
void dijkstra(int s)
{
    for(int i=1;i<=n;i++)
        dis[i]=inf,vis[i]=0;
    priority_queue<pii>q;
    dis[s]=0;
    q.push(mp(-dis[s],s));
    while(!q.empty())
    {
        int u=q.top().second;
        int d=q.top().first;
        q.pop();
        if(!vis[u])
        {
            vis[u]=1;
            for(int i=head[u];i;i=nxt[i])
            {
                int v=to[i];
                if(dis[v]>dis[u]+val[i])
                {
                    dis[v]=dis[u]+val[i];
                    pre[v]=u;
                    q.push(mp(-dis[v],v));
                }
            }
        }
    }
}
int fa[N];
int finds(int x)
{
    if(fa[x]==x)
        return x;
    return fa[x]=finds(fa[x]);
}
bool cmp(node a,node b)
{
    return a.z<b.z;
}
signed main()
{
    IOS;
    int m,s,t;
    cin>>n>>m>>s>>t;
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        addedge(u,v,w,1);
        addedge(v,u,w,1);
    }
    for(int i=1;i<=n;i++)
        fa[i]=i;
    sort(e+1,e+tot+1,cmp);
    int cnt=n;
    for(int i=1;i<=tot;i++)
    {
        if(cnt==1)
            break;
        int xx=finds(e[i].x),yy=finds(e[i].y);
        if(xx!=yy)
        {
            fa[xx]=yy;
            addedge(e[i].x,e[i].y,e[i].z,2);
            addedge(e[i].y,e[i].x,e[i].z,2);
            cnt--;
        }
    }
    dijkstra(s);
    int now=t;
    int res=-1;
    while(now!=s)
    {
        res=max(res,dis[now]-dis[pre[now]]);
        now=pre[now];
    }
    cout<<res<<endl;
}

公開された93元の記事 ウォンの賞賛9 ビュー4203

おすすめ

転載: blog.csdn.net/Joker_He/article/details/105196060