zoukankan      html  css  js  c++  java
  • Meeting (完全图 + 最段路)

    题目链接:https://vjudge.net/contest/362170#problem/I

    题意:

    给你n个点和m个集合,集合内的点可以相互到达,所花费的时间都为ti(1≤i≤m)。现在有两个人分别从点1和点n处出发,问两人最快的相遇时间是多少,并输出两人的相遇地点(可能有多个相遇地点)

    思路:

    对每个集合建立源点,源点到集合中的点的权值和集合中的点到源点的权值都为w/2,这样才能使得集合中的点之间的权值为w

    然后从1开始跑一遍最短路,从n开始跑一遍最短路,遍历找到最小值即可

    #pragma GCC optimize(3,"Ofast","inline")//O3优化
    #pragma GCC optimize(2)//O2优化
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    #include <sstream>
    #include <iostream>
    #include <cstring>
    
    #define LL long long
    #define ls nod<<1
    #define rs (nod<<1)+1
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define INF 0x3f3f3f3f
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    
    const double eps = 1e-10;
    const int maxn = 2e6 + 10;
    const LL mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    int head[maxn];
    int dis1[maxn],dis2[maxn];
    bool vis[maxn];
    int cnt;
    
    struct Edge{
        int to,next,val;
    }edge[maxn];
    
    
    
    void init(){
        cnt = 0;
        memset(head,-1, sizeof(head));
    }
    
    void add_edge(int u,int v,int w){
        edge[cnt].to = v;
        edge[cnt].val = w;
        edge[cnt].next = head[u];
        head[u] = cnt++;
    }
    
    void dijstra(int s,int dist[])
    {
        for (int i = 0;i < maxn;i++)
            dist[i] = INF;
        memset(vis,false, sizeof(vis));
        priority_queue<pii,vector<pii>,greater<pii>> q;
        dist[s] = 0;
        q.push({dist[s],s});
        while (!q.empty())
        {
            int now = q.top().second;
            q.pop();
            if (vis[now])
                continue;
            vis[now] = true;
            for (int i=head[now];i!=-1;i=edge[i].next)
            {
                int v = edge[i].to;
                if (dist[v]>dist[now]+edge[i].val)
                {
                    dist[v] = dist[now] + edge[i].val;
                    q.push({dist[v],v});
                }
            }
        }
    }
    
    int main() {
        int T;
        scanf("%d",&T);
        int t = 1;
        while (T--) {
            int n,m;
            scanf("%d%d",&n,&m);
            init();
            for (int i = 1;i <= m;i++) {
                int v;int s;
                scanf("%d%d",&v,&s);
                for (int k = 1;k <= s;k++) {
                    int y;
                    scanf("%d",&y);
                    add_edge(n+i,y,v);
                    add_edge(y,n+i,v);
                }
            }
            dijstra(1,dis1);
            dijstra(n,dis2);
            printf("Case #%d: ",t++);
            int ans = INF;
            for (int i = 1;i <= n;i++) {
                ans = min(max(dis1[i],dis2[i]),ans);
            }
            if (ans >= INF) {
                printf("Evil John
    ");
                continue;
            }
            printf("%.0lf
    ",ans/2.0);
            bool fl = false;
            for (int i = 1;i <= n;i++) {
                if (dis1[i] <= ans && dis2[i] <= ans) {
                    if (!fl) {
                        printf("%d", i);
                        fl = true;
                    }
                    else 
                        printf(" %d",i);
                }
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    LightningChartJS2.0即将火热推出,敬请期待!
    html转word
    Windows上使用Python2.7安装pip
    人工智能?.netcore一样胜任!
    远程浏览服务器上的文件
    C# winform间窗体传值简单Demo
    C#发送QQ邮箱
    各种文件用JS转Base64之后的data类型
    当你的VS2019没法自动补全了,或者自动补全按回车直接换行的时候
    easyUI filebox 获取文件对象
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12508158.html
Copyright © 2011-2022 走看看