CF #349 div1 B. World Tour

题目链接:http://codeforces.com/problemset/problem/666/B

大意是给一张有向图,选取四个点,使得走这四个点,任意两个点之间走最短路,总距离最长。

3000个点直接floyd肯定不行,但是注意到任意每条路距离都是1,其实可以枚举所有源点作bfs,求出距离数组。

然后对于每个点求出以这个点为入点和出点距离最大的3个点。再根据这个信息,枚举四个点中的中间两个,再枚举这两个点距离他们最远的那3*3种情况,判断是否有重复,没有重复的话,更新答案。

  1 #include <iostream>
  2 #include <vector>
  3 #include <algorithm>
  4 #include <string>
  5 #include <cstring>
  6 #include <cstdio>
  7 #include <math.h>
  8 #include <queue>
  9 #include <stack>
 10 #include <map>
 11 #include <set>
 12 using namespace std;
 13
 14
 15 const int N=3005;
 16
 17 vector<int>edge[N];
 18 int dis[N][N];
 19 int n;
 20 void bfs(int s) {
 21     queue< pair<int,int> >que;
 22     que.push(make_pair(s,0));
 23     dis[s][s]=0;
 24     while (!que.empty()) {
 25         pair<int,int> now=que.front();
 26         que.pop();
 27         int u=now.first,d=now.second;
 28         for (int i=0;i<edge[u].size();i++) {
 29             int v=edge[u][i];
 30             if (dis[s][v]>=0) continue;
 31             dis[s][v]=d+1;
 32             que.push(make_pair(v,d+1));
 33         }
 34     }
 35 }
 36 pair<int,int> in[N][3],out[N][3];
 37 void upd(pair<int,int> x,pair<int,int> *y) {
 38     for (int i=0;i<3;i++) {
 39         if (x>y[i]) {
 40             for (int j=2;j>i;j--) {
 41                 y[j]=y[j-1];
 42             }
 43             y[i]=x;
 44             break;
 45         }
 46     }
 47 }
 48 void solve() {
 49     memset(dis,-1,sizeof dis);
 50     for (int i=1;i<=n;i++){
 51         bfs(i);
 52         for (int j=0;j<3;j++) {
 53             in[i][j]=make_pair(-1,-1);
 54             out[i][j]=make_pair(-1,-1);
 55         }
 56     }
 57     for (int i=1;i<=n;i++) {
 58         for (int j=1;j<=n;j++) {
 59             if (i==j) continue;
 60             if (dis[i][j]==-1) continue;
 61             upd(make_pair(dis[i][j],i),in[j]);
 62             upd(make_pair(dis[i][j],j),out[i]);
 63         }
 64     }
 65     int best=0;
 66     int a=-1,b=-1,c=-1,d=-1;
 67     for (int i=1;i<=n;i++) {
 68         for (int j=1;j<=n;j++) {
 69             if (i==j) continue;
 70             if (dis[i][j]==-1) continue;
 71             for (int p=0;p<3;p++) {
 72                 if (in[i][p].first==-1) continue;
 73                 int ii=in[i][p].second;
 74                 if (ii==j) continue;
 75                 for (int q=0;q<3;q++) {
 76                     if (out[j][q].first==-1) continue;
 77                     int jj=out[j][q].second;
 78                     if (jj==i||jj==ii) continue;
 79
 80                     int tot=dis[ii][i]+dis[i][j]+dis[j][jj];
 81                     if (tot>best) {
 82                         best=tot;
 83                         a=ii;b=i;c=j;d=jj;
 84                     }
 85                 }
 86             }
 87         }
 88     }
 89     printf("%d %d %d %d\n",a,b,c,d);
 90 }
 91 int main () {
 92     int m;
 93     scanf("%d %d",&n,&m);
 94     for (int i=1;i<=m;i++) {
 95         int u,v;
 96         scanf("%d %d",&u,&v);
 97         edge[u].push_back(v);
 98     }
 99     solve();
100     return 0;
101 }

时间: 2025-01-15 17:32:38

CF #349 div1 B. World Tour的相关文章

CF#462 div1 D:A Creative Cutout

CF#462 div1 D:A Creative Cutout 题目大意: 原网址戳我! 题目大意: 在网格上任选一个点作为圆中心,然后以其为圆心画\(m\)个圆. 其中第\(k\)个圆的半径为\(\sqrt{k}\),\(m\)个圆的编号依次为\(1\)~\(m\). 定义一个格点的美妙值\(g(x,y)\)为包含了它的所有圆的编号之和. 定义\(f(n)\)为:当画了\(n\)个圆时,\(f(n) = \sum_{i,j\in R} g(i,j)\). 现在非常变态的问你一个非常无聊的恶心问

CF#345 (Div1)

身败名裂后的题解 先吐槽一下自己的代码能力&手速 A 06:52交的 B 29:34交的 C 52:49交的 开始一切正常 然后01:15左右发现C看起来是100W会爆栈,吓得我改成VC++开大了栈重交了一遍 于是赶紧去room里扫一波,然后发现一群用dfs的,感觉高兴极了,开始hack,然后成功-2-最后这些人system test都过啦- 我得赶紧去看一下CF的栈空间是多大啊 UPD: 我以后cf做题再也不管栈空间了-系统栈默认256M- 然后01:46的时候发现A有个地方没开long lo

CF #228 div1 B. Fox and Minimal path

题目链接:http://codeforces.com/problemset/problem/388/B 大意是用不超过1000个点构造一张边权为1的无向图,使得点1到点2的最短路的个数为给定值k,其中k为不超过1e9的正整数,输出邻接矩阵 构造方法也不止一种 有一种分层构造方法是这样的, 第i层的点与1号点距离为i-1 第一层放置1号点 第二层放置3号和4号点,分别与上一层的1号点相连,他们的最短路为1,且个数也为1 接下来每一层都会比上一层的点数要多1,第i+1层,首先与第i层的前i个点相连,

CF 472 div1 D. Contact ATC

#include <algorithm> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <queue> #include <set> #include <stack> #include <vector> const int N = 1e5

codeforces #305 div1 done

总算搞定了这一场比赛的题目,感觉收获蛮大 其中A,B,C都能通过自己的思考解决掉 D题思路好神,E题仔细想想也能想出来 以后坚持每两天或者一天做一场CF的div1的全套题目 除非有实在无法做出来的题目,每道题目还是都要写题解的 (我这算不算立flag? 本蒟蒻写的题解的链接: A:http://www.cnblogs.com/joyouth/p/5352953.html B:http://www.cnblogs.com/joyouth/p/5352932.html C:http://www.cn

cf训练2

CF 616 div1 A 题解 若 \(k \geq m-1\) ,我们可以任意指定顺序,我们求每个方案的最大值即可. 若 \(k < m-1\) ,发现我们有 \(m - k\) 种可能,取最小值即可. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define ll long long using namespace std; int read

2015 ACM-ICPC 北京赛区 网络赛 部分 题解

由于博主水平及智商不足,所以暂时只能放出下列的题目的题解. A B D F G H 需要其他题解请自行前往 http://talk.icpc-camp.org/ 题目地址:hihocoder 1227-1236 A.  The Cats' Feeding Spots 题意:给出M个点,求以其中一个点为圆心,最小半径的圆,使得这个圆里恰好有N个点. (半径一定要是整数,且点不能恰好在圆上). 方法:暴力,稍微注意一下精度什么的就好了,1A. 1 #include <bits/stdc++.h>

Codeforces Round #243

CF 243  DIV1 & DIV2 DIV2的A和B都太水,直接暴力搞就可以的. DIV2A 1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2014/4/30 19:42:51 4 File Name :E:\2014ACM\Codeforces\CF243\DIV2_A.cpp 5 ****************************************

(中等) CF 576D Flights for Regular Customers (#319 Div1 D题),矩阵快速幂。

In the country there are exactly n cities numbered with positive integers from 1 to n. In each city there is an airport is located. Also, there is the only one airline, which makes m flights. Unfortunately, to use them, you need to be a regular custo