• HDU 5521 Meeting 【拆点+最短路】


    题目链接

    题意

    给m个由图中结点组成的点集,点集中的点两两连通且距离为相等的ti。现有两人分别从1和N点处同时出发吗,问能否相遇以及相遇的最短时间。

    分析

    很容易想到直接分别以点1和点N为起始点求最短路,再遍历各个点即可求得最短相遇时间。然而建图上却有问题:这个题中的边是以点集的形式给出,极端情况下可能会出现有1E12条边的稠密图。
    这时就要利用点集中的点之间距离相等这个性质,拆点来建图。将点集抽象成一个点,将点集中的每个连一条长为ti/2的边到这个点集的点。 这样做可以大大减少边的数量。另外为了防止出现浮点数,可以直接把每个边变成ti而不是ti/2最后在最短时间上除以2就可以了

    AC代码

    //HDU 5521 Meeting
    //AC 2016-08-10 16:43:30
    //Shortest Path
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <set>
    #include <string>
    #include <map>
    #include <queue>
    #include <deque>
    #include <list>
    #include <sstream>
    #include <stack>
    using namespace std;
    
    #define cls(x) memset(x,0,sizeof x)
    #define inf(x) memset(x,0x3f,sizeof x)
    #define neg(x) memset(x,-1,sizeof x)
    #define ninf(x) memset(x,0xc0,sizeof x)
    #define st0(x) memset(x,false,sizeof x)
    #define st1(x) memset(x,true,sizeof x)
    #define INF 0x3f3f3f3f
    #define lowbit(x) x&(-x)
    #define input(x) scanf("%d",&(x))
    #define bug cout<<"here"<<endl;
    //#define debug
    
    int T;
    int n,m;
    
    struct node
    {
        int pos;
        int dist;
        bool operator< (const node &rhs) const
        {
            return dist>rhs.dist;
        }
    }p,q;
    
    vector<node> G[1100100];
    
    int dist1[1100100],dist2[1100100];
    
    void dijkstra(int beg,int dist[])
    {
        priority_queue<node> DIJ;
        p.pos=beg;p.dist=0;
        dist[beg]=0;
        DIJ.push(p);
        while(DIJ.size())
        {
            p=DIJ.top();DIJ.pop();
            if(dist[p.pos]>p.dist) continue;
            for(int i=0;i<G[p.pos].size();++i)
            {
                q.pos=G[p.pos][i].pos;
                q.dist=p.dist+G[p.pos][i].dist;
                if(dist[q.pos]>q.dist)
                {
                    dist[q.pos]=q.dist;
                    DIJ.push(q);
                }
            }
        }
        return;
    }
    
    int main()
    {
        #ifdef debug
            freopen("E:\Documents\code\input.txt","r",stdin);
            freopen("E:\Documents\code\output.txt","w",stdout);
        #endif
        int T;input(T);
        for(int kase=1;kase<=T;++kase)
        {
            scanf("%d %d",&n,&m);
            for(int i=0;i<=n+m;++i) G[i].clear();
            int t,s,a;
            for(int i=1;i<=m;++i)
            {
                scanf("%d %d",&p.dist,&s);
                for(int j=0;j<s;++j)
                {
                    input(a);p.pos=i+n;
                    G[a].push_back(p);
                    p.pos=a;
                    G[i+n].push_back(p);
                }
            }
            inf(dist1);inf(dist2);
            dijkstra(1,dist1);dijkstra(n,dist2);
            int res=INF;
            for(int i=1;i<=n;++i)
                res=min(res,max(dist1[i],dist2[i]));
            printf("Case #%d: ",kase);
            if(res>=INF) printf("Evil John
    ");
            else
            {
                printf("%d
    ",res/2);
                bool first=1;
                for(int i=1;i<=n;++i)
                {
                    if(max(dist1[i],dist2[i])==res)
                    {
                        if(!first) putchar(' ');
                        first=0;
                        printf("%d",i);
                    }
                }
                putchar('
    ');
            }
        }
        return 0;
    }
  • 相关阅读:
    PYTHON ASYNCIO: FUTURE, TASK AND THE EVENT LOOP
    【Python】迭代器、生成器、yield单线程异步并发实现详解
    Python函数式编程
    利用python yielding创建协程将异步编程同步化
    Understanding Asynchronous IO With Python 3.4's Asyncio And Node.js
    MySQL视图-(视图创建,修改,删除,查看,更新数据)
    菜鸟使用MySQL存储过程and临时表,供新手参考,请高手斧正
    Mysql存储过程(六)——存储过程中使用临时表
    show processlist结果筛选
    大数据文件编辑
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6580590.html
Copyright © 2020-2023  润新知