[BFS]JZOJ 4671 World Tour
Description
Cicasso是一个著名的雕塑家。现在他想去城市之间旅游,他是一个聪明的人,所以从一个城市到另一个城市他只会走最短路。他想游览全国的风景,所以他想走的路的总长度尽量长,但是经费有限,他只能去四个城市,而且这四个城市不能重复(在途中经过的城市不计算,例如
注意,道路是单向路,并且距离都为1。
Input
在第一行有两个整数n和m(4<=n<=3000,3<=m<=5000),n代表城市数,m代表单向边的数量接下来m行有两个整数ui,vi(ui,vi<=n)——代表一条从ui到vi的单向边,注意ui和vi可能相同,并且同两个城市之间可能有多条边
Output
输出四个整数,代表Cicasso要旅游的路线。Sample Input
8 9
1 2
2 3
3 4
4 1
4 5
5 6
6 7
7 8
8 5
Sample Output
2 1 8 7
d(2,1)=3,d(1,8)=7,d(8,7)=3,总共的距离等于13
Data Constraint
对于10% n<=10对于20% n<=100
对于 30% n<=1000
对于100% n<=3000
分析
我还以为是什么奇怪的东西呢,点就四个
我们只需要预处理出距离每个点最远和次远的点的距离和点,然后枚举四个点中间的两个点,先选择它们的最远点,若最远点重合,则选次远点
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
![[BFS]JZOJ 4671 World Tour 随笔 第2张 [BFS]JZOJ 4671 World Tour 随笔 第2张](https://www.liuyixiang.com/zb_users/theme/Lucky/style/image/grey.gif)
#include <iostream> #include <cstdio> #include <memory.h> #include <queue> using namespace std; const int N=3e3+10; const int Inf=0x3f3f3f3f; struct Edge { int u,v,nx; }g[2*N]; int cnt,list[N],d[N][N],mx[N][2],revmx[N][2]; int n,m; void Add(int u,int v) { g[++cnt]=(Edge){u,v,list[u]};list[u]=cnt; } void BFS() { queue<int> from,to; while (!from.empty()) from.pop(); while (!to.empty()) to.pop(); for (int i=1;i<=n;i++) d[i][i]=0,from.push(i),to.push(i); while (!from.empty()) { int f=from.front(),u=to.front();from.pop();to.pop(); for (int i=list[u];i;i=g[i].nx) if (d[f][g[i].v]>d[f][u]+1) { d[f][g[i].v]=d[f][u]+1; from.push(f);to.push(g[i].v); } } } void Pre_Process() { for (int i=1;i<=n;i++) { mx[i][0]=mx[i][1]=revmx[i][0]=revmx[i][1]=i; for (int j=1;j<=n;j++) if (i!=j) { if (d[i][j]!=Inf) if (d[i][j]>d[i][mx[i][0]]) mx[i][1]=mx[i][0],mx[i][0]=j; else if (d[i][j]>mx[i][1]) mx[i][1]=j; if (d[j][i]!=Inf) if (d[j][i]>d[revmx[i][0]][i]) revmx[i][1]=revmx[i][0],revmx[i][0]=j; else if (d[j][i]>d[revmx[i][1]][i]) revmx[i][1]=j; } } } int main() { scanf("%d%d",&n,&m); for (int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),Add(u,v); memset(d,0x3f,sizeof d);BFS(); Pre_Process(); int ans=0,a1,a2,a3,a4; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i!=j&&d[i][j]!=Inf) for (int k=0;k<2;k++) for (int l=0;l<2;l++) { int u1=revmx[i][k],v1=mx[j][l]; if (u1==v1||u1==i||u1==j||v1==i||v1==j) continue; if (d[u1][i]+d[i][j]+d[j][v1]>ans) ans=d[u1][i]+d[i][j]+d[j][v1],a1=u1,a2=i,a3=j,a4=v1; } printf("%d %d %d %d\n",a1,a2,a3,a4); }View Code

更多精彩