题意:给你一个有向图,用n条路径覆盖(点可重复),使得未被覆盖的点权值最小最大
思考:
先缩点(不过貌似本题无环),变有向无环图(不一定连通)
二分+网络流最小路径覆盖?
查了查发现最小路径覆盖不可重点,此题是可重点的最小路径覆盖(需保证无环)
怎么又去看题解了?!
floyed求一下传递闭包即可转化
时间复杂度O(m3+m2log)
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
const int N=504;
int n,m,val[N],vis[N],b[N],mat[N],a[N][N];
inline bool comp(int x,int y){
return val[x]<val[y];
}
bool dfs(int x,int mid){
for(int i=1,v;i<=mid;i++){
v=b[i];
if(a[x][v]&&!vis[v]){
vis[v]=1;
if(!mat[v]||dfs(mat[v],mid)){mat[v]=x;return 1;}
}
}
return 0;
}
int main(){
m=read()+1;n=read();
for(int i=1,k;i<=n;i++){
val[i]=read();
k=read();
while(k--)a[i][read()]=1;
b[i]=i;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]|=a[i][k]&a[k][j];
sort(b+1,b+n+1,comp);
int l=0,r=n,mid,path;
while(l<r){
int mid=l+r+1>>1;
path=mid;
memset(mat,0,sizeof(mat));
for(int i=1;i<=mid;i++){
memset(vis,0,sizeof(vis));
if(dfs(b[i],mid))path--;
}
if(path<=m)l=mid;
else r=mid-1;
}
if(r==n)puts("AK");
else cout<<val[b[r+1]]<<"
";
return (0-0);
}