• AtCoder Regular Contest 061 E


    具体题解又要搬大哥的了,嘿嘿~
    请点击:G点我
    这道题目的难点就是同一家公司的路直接走不需要再花费,然后多了一个公司这个东西,这个不像是边的副权值(瞎说的)之类的东西,这是对于路来说的,路的属性。。。
    其实稀里哗啦说了那么多,真的觉得这个方法实在是太棒了;
    将点和公司组合构造新点,然后新点的路我们可以构造,根据题意,同一家公司的路不需要花费即(u,c)《=》(v,c)之间距离=0;
    然后u到(u,c)是1,v到(v,c)是1,建双向边。
    这可以解决的是同一家公司的路不花费,把点边点根据题意拆分太棒了;
    这里再贴一份我的挫代码:

    //#include <bits/stdc++.h>
    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<map>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    /*
    最短路拆点,跑最短路;
    */
    
    const int N=1e6+10;
    const int INF=0x3f3f3f3f;
    
    map<pair<int,int>,int>mp;
    
    struct asd{
        int to;
        int w;
        int next;
    };
    int head[N*8],tol,dd;
    asd q[N*8];
    int num[N*8];
    bool vis[N*8];
    int dis[N*8];
    int n,m;
    int que[N];
    int s,t;
    
    int spfa()
    {
        s=0;
        t=1;
        for(int i=1;i<=dd+1;i++)
        {
            dis[i]=INF;
            vis[i]=0;
            num[i]=0;
        }
        dis[1]=0;
        vis[1]=num[1]=1;
        que[s]=1;
        while(s<t)
        {
            int u=que[s];
            s++;
            vis[u]=0;
            for(int v=head[u];v!=-1;v=q[v].next)
            {
                int i=q[v].to;
                if(dis[i]>q[v].w+dis[u])
                {
                    dis[i]=q[v].w+dis[u];
                    if(!vis[i])
                    {
                        num[i]++;
                        if(num[i]>=dd)
                            return -2;
                        vis[i]=1;
                        que[t]=i;
                        t++;
                    }
                }
            }
        }
        if(dis[n]!=INF)
            return dis[n];
        else
            return -2;
    }
    int getid(int x,int y)
    {
        if(mp.find({x,y})!=mp.end())
            return mp[{x,y}];
        return mp[{x,y}]=++dd;
    }
    void init()
    {
        dd=n;
        tol=0;
        memset(head,-1,sizeof(head));
    }
    void add(int a,int b,int c)
    {
        q[tol].w=c;
        q[tol].to=b;
        q[tol].next=head[a];
        head[a]=tol++;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        init();
        for(int i=0;i<m;i++)
        {
            int x,y,c;
            scanf("%d%d%d",&x,&y,&c);
            int xx=getid(x,c);
            int yy=getid(y,c);
            add(xx,yy,0);
            add(yy,xx,0);
            add(x,xx,1);
            add(xx,x,1);
            add(y,yy,1);
            add(yy,y,1);
        }
        printf("%d
    ",spfa()/2);
        return 0;
    }
  • 相关阅读:
    nginx 配置https 负载均衡
    MyCAT+MySQL搭建高可用企业级数据库集群视频课程
    Java数字签名算法--RSA
    bootstrap在iframe框架中实现由子页面在顶级页面打开模态框(modal)
    bootstrap-treeview 自定义实现双击事件
    Java多线程之内存可见性
    Java实现责任链模式
    JVM(HotSpot) 7种垃圾收集器的特点及使用场景
    jQuery的noConflict以及插件扩展
    JavaScript事件漫谈
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934786.html
Copyright © 2020-2023  润新知