图论难题训练

这篇博客介绍了三个图论问题的解决方案,包括HDU 6350 Always Online的仙人掌图最大流问题,CF1240F Football的赛事安排优化,以及AGC017E Jigsaw的拼图匹配。通过动态规划和增广路寻找策略,解决实际场景中的复杂问题。
摘要由CSDN通过智能技术生成

HDU 6350 Always Online

给出一个仙人掌,求
∑ s , t s ⊕ t ⊕ maxflow ⁡ ( s , t ) \sum_{s,t}s \oplus t \oplus \operatorname{maxflow}(s,t) s,tstmaxflow(s,t)

对于一棵树的情况, maxflow ⁡ ( s , t ) \operatorname{maxflow}(s,t) maxflow(s,t)就是 s , t s,t s,t的简单路径上最短的一条边的权值。
用并查集从大到小枚举每条边,然后将边两端的点的集合合并,合并前可以通过统计每一位两边各有几个 0 / 1 0/1 0/1来维护题目需要的和。

对于仙人掌的情况,如果割了一条环上的边,那么就一定还需要割另一条环上的边,实际上是将每一个环分成了两个边的集合,两个集合各选最小的一条边删去。
那么环上最小权值的边一定会被删去,我们提前把环上权值最小的边删去后给环上的其他边加上这条边的权值,图就变成了一棵树,套用上述做法即可。

A C   C o d e \mathcal AC \ Code AC Code

#include<bits/stdc++.h>
#define maxn 200005
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
#define LL unsigned long long
using namespace std;

char cb[1<<16],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<16,stdin),cs==ct)?0:*cs++)
void read(int &res){
   
	char ch;
	for(;!isdigit(ch=getc()););
	for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
}

int n,m;
int sx[maxn],ty[maxn],cw[maxn],c[maxn];
int info[maxn],Prev[maxn<<1],to[maxn<<1],cnt_e=1;
void Node(int u,int v){
    Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v; }

int dfn[maxn],low[maxn],sta[maxn],tot;
void trj(int u,int ff){
   
	dfn[u] = low[u] = ++tot;
	for(int i=info[u],v;i;i=Prev[i]) if(!dfn[v=to[i]]){
   
		sta[++sta[0]] = i;
		trj(v,u);
		low[u] = min(low[u] , low[v]);
		if(low[v] > dfn[u]){
   
			for(int t=-1;to[t] != v;)
				t = sta[sta[0]--];
		}
		if(low[v] == dfn[u]){
   
			int loc = -1;
			vector<int>G;
			for(int t=-1;to[t] != v;){
   
				t = sta[sta[0]--];
				if(loc == -1 || cw[t / 2] < cw[loc])
					loc = t / 2;
				G.push_back(t / 2);
			}
			int val = cw[loc];
			rep(j,0,G.size
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值