• UESTC 1955 喜马拉雅山上的猴子


    题目:http://www.qscoj.cn/#/problem/show/1955

    我们可以先用spfa跑出每2个点之间的距离

    之后枚举b点和c点,再枚举从c点出发和到达b点的最大距离

    对距离排序后先找到的答案更优,所以找到后就可以退出循环

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    const int N=1e5+5;
    int head[N],to[N],val[N],nt[N],d[1005][1005];
    bool vis[N];
    int tot;
    void addedge(int u,int v,int w)
    {
        nt[++tot]=head[u];
        val[tot]=w;
        to[tot]=v;
        head[u]=tot;
    }
    void spfa(int x)
    {
        memset(d[x],0x3f,sizeof(d[x]));
        memset(vis,0,sizeof(vis));
        queue<int> que;
        que.push(x);
        d[x][x]=0;
        while(!que.empty())
        {
            int t=que.front();que.pop();
            vis[t]=0;
            for(int i=head[t];i!=-1;i=nt[i])
                if (d[x][to[i]]>d[x][t]+val[i])
                {
                    d[x][to[i]]=d[x][t]+val[i];
                    if (!vis[to[i]])
                    {
                        que.push(to[i]);
                        vis[to[i]]=1;
                    }
                }
        }
    }
    struct p
    {
        int x,y;
        p(int xx,int yy)
        {
            x=xx;
            y=yy;
        }
        bool operator >(p t)const
        {
            return y>t.y;
        }
    };
    vector<p> a[N],b[N];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(head,-1,sizeof(head));
        tot=0;
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            addedge(x,y,z);
        }
        for(int i=1;i<=n;i++)
            spfa(i);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if (i!=j)
                {
                    if (d[i][j]!=0x3f3f3f3f) a[i].push_back(p(j,d[i][j]));
                    if (d[j][i]!=0x3f3f3f3f) b[i].push_back(p(j,d[j][i]));
                }
        for(int i=1;i<=n;i++)
        {
            sort(a[i].begin(),a[i].end(),greater<p>());
            sort(b[i].begin(),b[i].end(),greater<p>());
        }
        int ans=0;
        int aa,bb,cc,dd;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if (i!=j&&d[i][j]!=0x3f3f3f3f)
                    for(int ii=0;ii<b[i].size();ii++)
                    {
                        int flag=0;
                        for(int jj=0;jj<a[j].size();jj++)
                            if (b[i][ii].x!=a[j][jj].x&&b[i][ii].x!=j&&a[j][jj].x!=i)
                            {
                                int t=b[i][ii].y+a[j][jj].y+d[i][j];
                                if (t>ans)
                                {
                                    ans=t;
                                    aa=b[i][ii].x;
                                    bb=i;
                                    cc=j;
                                    dd=a[j][jj].x;
                                }
                                flag=1;
                                break;
                            }
                        if (flag) break;
                    }
            }
        printf("%d %d %d %d
    ",aa,bb,cc,dd);
        return 0;
    }
    

      

  • 相关阅读:
    Bitmap\Bytes\BitmapImage相互转换
    枚举值为什么使用1,2,4,8,16,32等2的幂方(转)
    获取电脑信息
    操作内存的帮助类
    C#调用DLL(整理)
    [原]java集合类TreeMap和TreeSet
    [原]《面试题精选》08.颠倒句子中单词的顺序
    [原]数据结构与对象的区别
    [原]初步了解Hadoop平台
    [原]《程序员面试题精选》06.查找最小的k个元素
  • 原文地址:https://www.cnblogs.com/bk-201/p/9313647.html
Copyright © 2020-2023  润新知