2026天梯赛
这个比赛好唐诗啊,要求真jb多。
前面的题太简单了,最后两题难度一上来,我还没感觉,以为一样简单。如果从倒数第二题开始做的话感觉就可以想出来。
倒数第二题就是个最小点覆盖的版子题,结果一直往贪心的方面去想了。
复习一下最小点覆盖。在一个二分图里最小点覆盖的大小等于二分图最大匹配。
最后答案就是 n+ans.
int n;
struct Dinic{
struct edge{
int u,v,cap,flow;
};
vector<edge>edges;
vector<int>g[N];
int cur[N],d[N];
bool vis[N];
inline void add(int u,int v,int cap){
edges.push_back({u,v,cap,0});
edges.push_back({v,u,0,0});
int t=edges.size();
g[u].push_back(t-2);
g[v].push_back(t-1);
}
inline bool bfs(int s,int t){
memset(vis,0,sizeof vis);
queue<int>q;
q.push(s);
d[s]=0;vis[s]=1;
while(q.size()){
int u=q.front();q.pop();
for(auto i:g[u]){
auto e=edges[i];
if(!vis[e.v]&&e.cap>e.flow){
vis[e.v]=1;
d[e.v]=d[u]+1;
q.push(e.v);
}
}
}
return vis[t];
}
inline int dfs(int u,int a,int t){
if(u==t||a==0)return a;
int flow=0,f;
for(int &i=cur[u];i<g[u].size();i++){
auto& e=edges[g[u][i]];
if(d[u]+1==d[e.v]&&(f=dfs(e.v,min(a,e.cap-e.flow),t))>0){
e.flow+=f;
edges[g[u][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
return flow;
}
inline int maxflow(int s,int t){
int flow=0;
while(bfs(s,t)){
memset(cur,0,sizeof cur);
flow+=dfs(s,inf,t);
}
return flow;
}
void clear(){
up(i,0,2*n+1)g[i].clear();
memset(cur,0,sizeof cur);
memset(d,0,sizeof d);
edges.clear();
}
}E;
void solve(){
E.clear();
cin>>n;
int u,v;
up(i,1,n){
cin>>u>>v;
E.add(u,n+v,1);
}
up(i,1,n)E.add(0,i,1),E.add(i+n,2*n+1,1);
cout<<n+E.maxflow(0,2*n+1)<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin>>T;
while(T--){
solve();
}
return 0;
}
最后一道题很神秘的样子。简单来说找有多少个序列b满足 \(a_{b_i}=b_{a_i}\)
不会

浙公网安备 33010602011771号