Codeforces 66D World tour BFS+枚举

来源:互联网 发布:diy图片制作软件 编辑:程序博客网 时间:2024/06/05 02:58

点击打开链接

题意:给一个有向图 求出4个点最短距离和最大 (n<=3e3)

d(a+b+c+d)要最大 枚举b,c 因为路程要最大 找到离b最远a和离c最远d即可

#include <bits/stdc++.h>#include <queue>#include <vector>using namespace std;const int N=5e3+20;const long long inf=2e7;vector<int> e[N];int n,m,A,B,C,Y;int d[N][N],vis[N],used[N];int ans=0;struct node{int d,to;};bool cmp(node a,node b){return a.d>b.d;}vector<node> p1[N],p2[N];void bfs(int x){memset(vis,0,sizeof(vis));queue<int> q;q.push(x);vis[x]=1;d[x][x]=0;while(!q.empty()){int u=q.front();q.pop();for(int i=0;i<e[u].size();i++){int v=e[u][i];if(d[x][u]<inf&&d[x][v]>d[x][u]+1){d[x][v]=d[x][u]+1;vis[v]=1;q.push(v);}}}}int main(){cin>>n>>m;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j]=inf;while(m--){int u,v;cin>>u>>v;e[u].push_back(v);//单向无权 }for(int i=1;i<=n;i++)bfs(i);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(d[i][j]!=inf&&i!=j){p1[i].push_back((node){d[i][j],j});//c->dp2[j].push_back((node){d[i][j],i});//a->b}}} //提前排序:快速找到最大的d[i][j] for(int i=1;i<=n;i++){sort(p1[i].begin(),p1[i].end(),cmp);sort(p2[i].begin(),p2[i].end(),cmp);}int ans=0;for(int b=1;b<=n;b++){for(int c=1;c<=n;c++){if(b==c||d[b][c]>=inf) continue; //枚举前4大的,防止离b最近的是c或者是d for(int i=0;i<p2[b].size()&&i<4;i++){if(p2[b][i].to==c) continue;//a=(c)->b路径 for(int l=0;l<p1[c].size()&&l<4;l++){if(p1[c][l].to==p2[b][i].to|| p1[c][l].to==b) continue;int res=p2[b][i].d+d[b][c]+p1[c][l].d;if(res>ans){ans=res;A=p2[b][i].to;B=b;C=c;Y=p1[c][l].to;}}}}}printf("%d %d %d %d\n",A,B,C,Y);return 0;}


0 0
原创粉丝点击