标签: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; }
标签:gcc cst def void color val 链接 top cto
原文地址:https://www.cnblogs.com/-Ackerman/p/12508158.html