题目链接:
https://codeforces.com/gym/101987/attachments
题意:
给出$n$个节点,$m$条边
对于所有$(a,b)$,求出$a$到$b$路径中最小边的最大值
注意两个隐藏条件
1.不存在环
2.如果$a$到$b$,$b$到$c$,那么$len(a,b)>len(b,c)$
数据范围:
$1\leq n \leq 500$
$1\leq m \leq 250000$
分析:
一条路径最小值
AC代码:
#include<bits/stdc++.h> #define ll long long #define pii pair<int,int> using namespace std; const int maxn=500+7; int S[maxn][maxn]; int ma[maxn][maxn]; int sk[maxn],top,cnt,n,m; int cnt2,f[maxn],nex[maxn*maxn],to[maxn*maxn],w[maxn*maxn],vis[maxn]; void add(int a,int b,int x){ cnt2++; to[cnt2]=b; w[cnt2]=x; nex[cnt2]=f[a]; f[a]=cnt2; } void bfs(int x){ queue<int>que; que.push(x); vis[x]=1; while(que.size()){ int v=que.front(); que.pop(); for(int i=f[v];i;i=nex[i]){ int t=to[i]; if(vis[t]==0){ que.push(t); vis[t]=1; } } } for(int i=1;i<=m;i++){ if(vis[i]) for(int j=f[i];j;j=nex[j]){ S[x][to[j]]=max(S[x][to[j]],w[j]); } } } int main(){ scanf("%d %d",&m,&n); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&ma[i][j]); if(ma[i][j]==0)ma[i][j]=1e7; } for(int i=1;i<=m;i++){ for(int j=i+1;j<=m;j++){ int a=0,b=0; for(int k=1;k<=n;k++){ if(ma[k][i]<ma[k][j])a++; else if(ma[k][i]>ma[k][j])b++; } if(a>b)add(i,j,a); else if(b>a)add(j,i,b); } } for(int i=1;i<=m;i++){ memset(vis,0,sizeof(vis)); bfs(i); } for(int i=1;i<=m;i++){ int fla=1; for(int j=1;j<=m;j++){ if(i==j)continue; if(S[i][j]<S[j][i]){ fla=0; break; } } if(fla)sk[++top]=i; } for(int i=1;i<=top;i++){ printf("%d",sk[i]); if(i==top)printf("\n"); else printf(" "); } return 0; }
原文地址:https://www.cnblogs.com/carcar/p/11597046.html
时间: 2024-10-09 17:58:34