码迷,mamicode.com
首页 > 其他好文 > 详细

Meeting (完全图 + 最段路)

时间:2020-03-17 08:31:08      阅读:45      评论:0      收藏:0      [点我收藏+]

标签:gcc   cst   def   void   color   val   链接   top   cto   

题目链接: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\n");
            continue;
        }
        printf("%.0lf\n",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("\n");
    }
    return 0;
}

 

Meeting (完全图 + 最段路)

标签:gcc   cst   def   void   color   val   链接   top   cto   

原文地址:https://www.cnblogs.com/-Ackerman/p/12508158.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!