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}\)

不会

posted @ 2026-04-20 22:04  LiQXing  阅读(9)  评论(0)    收藏  举报