题目链接:CF786E

输出方案暗示网络流

我们考虑最朴素的建图

由源点\(s\)连向所有人,容量为1;树上所有的边视作节点连向\(t\),流量为1;人向其路径上所有的树边连边,流量为\(inf\),跑最小割即可

然而我们发现这样的话网络图中的边的数据规模达到了\(O(n^2)​\),肯定炸掉

于是考虑优化建图

我们将一条路径拆成\(log\)段,用\((i,j)\)表示由节点\(i\)跳到其\(2^j\)层父亲

注意到\((i,j)\)包含着\((i,j-1),(i+2^{j-1},j-1)\),因此我们考虑也将其连上容量为\(inf\)的边(类似于标记下放?不熟悉的可以做SCOI2016萌萌哒,一个区间上的问题)

原来的图中将树边连向\(t\)也就变成了将边\((i,0)\)连向\(t\)(此时\(t>1​\))

那么新图的点数和边数的规模均维持在\(O(nlogn)\)可以维护

然而毒瘤题还要输出方案

我们考虑从源点\(dfs\),如果当前找到的一条边有流量说明还未割开

如果代表人的点被割开说明要标记这个人;如果某条原来与\(t\)相连的树边未被割开说明要标记这一条树边

预处理时存下相对应的编号即可

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x)&(-x)
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,a,b) for (int i=a;i>=b;i--)
#define maxd 1000000007
typedef long long ll;
const int N=100000;
const double pi=acos(-1.0);
struct treenode{
int to,nxt,id;
}tree[40040];
int all1=0,head1[40040]; struct flownode{
int to,nxt,flow;
}sq[10004000];
int all=1,head[501000],cur[500500],dept[500500];
bool vis[500500];
queue<int> q; int n,m,st[20020][20],fa[20020][20],tot=0,dep[20020],s,t,
a[500500],b[500500]; int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
} void addedge(int u,int v,int id)
{
all1++;tree[all1].nxt=head1[u];tree[all1].to=v;tree[all1].id=id;head1[u]=all1;
} void add(int u,int v,int f)
{
all++;sq[all].nxt=head[u];sq[all].to=v;sq[all].flow=f;head[u]=all;
all++;sq[all].nxt=head[v];sq[all].to=u;sq[all].flow=0;head[v]=all;
} void dfs(int u,int fu)
{
dep[u]=dep[fu]+1;fa[u][0]=fu;
rep(i,1,15) st[u][i]=(++tot);
rep(i,1,15)
{
if (fa[u][i-1])
{
fa[u][i]=fa[fa[u][i-1]][i-1];
add(st[u][i],st[u][i-1],maxd);
add(st[u][i],st[fa[u][i-1]][i-1],maxd);
}
}
int i;
for (i=head1[u];i;i=tree[i].nxt)
{
int v=tree[i].to;
if (v==fu) continue;
st[v][0]=(++tot);b[tree[i].id]=tot;
dfs(v,u);
}
} void query_lca(int u,int v,int now)
{
if (dep[u]<dep[v]) swap(u,v);
int tmp=dep[u]-dep[v];
per(i,15,0)
{
if ((tmp>>i)&1)
{
add(now,st[u][i],maxd);
u=fa[u][i];
}
}
if (u==v) return;
per(i,15,0)
{
if (fa[u][i]!=fa[v][i])
{
add(now,st[u][i],maxd);add(now,st[v][i],maxd);
u=fa[u][i];v=fa[v][i];
}
}
add(now,st[u][0],maxd);add(now,st[v][0],maxd);
} void init()
{
n=read();m=read();
rep(i,1,n-1)
{
int u=read(),v=read();
addedge(u,v,i);addedge(v,u,i);
}
rep(i,0,15) st[0][i]=(++tot);st[1][0]=(++tot);
dfs(1,0);
rep(i,1,m)
{
a[i]=(++tot);add(s,tot,1);
int u=read(),v=read();
query_lca(u,v,tot);
}
t=(++tot);
rep(i,2,n) add(st[i][0],t,1);
} bool bfs()
{
memset(vis,0,sizeof(vis));
memset(dept,0,sizeof(dept));
q.push(s);vis[s]=1;
while (!q.empty())
{
int u=q.front(),i;q.pop();
for (i=head[u];i;i=sq[i].nxt)
{
int v=sq[i].to;
if ((sq[i].flow) && (!vis[v]))
{
vis[v]=1;q.push(v);
dept[v]=dept[u]+1;
}
}
}
if (!vis[t]) return 0;
rep(i,0,t) cur[i]=head[i];
return 1;
} int dfs(int now,int t,int lim)
{
if ((!lim) || (now==t)) return lim;
int i,sum=0;
for (i=cur[now];i;i=sq[i].nxt)
{
int v=sq[i].to;cur[now]=i;
if (dept[v]==dept[now]+1)
{
int f=dfs(v,t,min(sq[i].flow,lim));
if (f)
{
sq[i].flow-=f;
sq[i^1].flow+=f;
sum+=f;lim-=f;
if (!lim) break;
}
}
}
return sum;
} void dfsans(int u)
{
vis[u]=1;
int i;
for (i=head[u];i;i=sq[i].nxt)
{
int v=sq[i].to;
if ((!vis[v]) && (sq[i].flow)) dfsans(v);
}
} void work()
{
int ans=0;
while (bfs()) ans+=dfs(s,t,maxd);
memset(vis,0,sizeof(vis));
dfsans(0);
printf("%d\n",ans);
int cnt=0;
rep(i,1,m) if (!vis[a[i]]) cnt++;
printf("%d ",cnt);
rep(i,1,m) if (!vis[a[i]]) printf("%d ",i);printf("\n");
cnt=0;
rep(i,1,n-1) if (vis[b[i]]) cnt++;
printf("%d ",cnt);
rep(i,1,n-1) if (vis[b[i]]) printf("%d ",i);
} int main()
{
init();
work();
return 0;
}

codeforces 786E ALT的更多相关文章

  1. Codeforces 786E. ALT 最小割+倍增

    E. ALT http://codeforces.com/problemset/problem/786/E 题意: 给出一棵 n 个节点的树与 m 个工人.每个工人有一条上下班路线(简单路径),一个工 ...

  2. 【Codeforces】【网络流】【树链剖分】【线段树】ALT (CodeForces - 786E)

    题意 现在有m个人,每一个人都特别喜欢狗.另外还有一棵n个节点的树. 现在每个人都想要从树上的某个节点走到另外一个节点,且满足要么这个人自带一条狗m,要么他经过的所有边h上都有一条狗. 2<=n ...

  3. 【Codeforces】【#295】【Div.1】

    嘛,一直以来蒟蒻都没怎么打过CF……现在还是蓝名狗……今天跟着zyf打了一场virtual,果断一题滚粗

  4. CodeForces - 344A Magnets (模拟题)

    CodeForces - 344A id=46664" style="color:blue; text-decoration:none">Magnets Time ...

  5. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  6. [No000093]按住Alt 再按数字键敲出任意汉字和字符!

    1.在notepad里,(中文系统下) 按住Alt 然后按52946最后放开Alt 按住Alt 然后按45230最后放开Alt 按住Alt 然后按50403最后放开Alt 你会看到"我爱你& ...

  7. [No00008B]远程桌面发送“Ctrl+Alt+Delete”组合键调用任务管理器

    向远程桌面发送"Ctrl+Alt+Delete"组合键的两种方法 1.在本地按下Ctrl+Alt+End,可以成功发送"Ctrl+Alt+Delete"组合键! ...

  8. 平常看到的Alt+xx 快捷键用法

    1. 先按Alt, 哪一个菜单对应的字符是有划线的. 2. 输入对应的字符打开相应的菜单, 3 再输入相应的字符打开子菜单

  9. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

随机推荐

  1. Dynamics 365-如何指定邮件收件人的地址

    如果CRM Entity勾选了Sending Email,那么这个Entity的Records是可以直接作为Email的收件人使用的,而邮件地址是Entity的Primary Email字段. 在我们 ...

  2. 可视化设计,类Excel的快速开发平台

    活字格Web应用生成器,是可视化设计,类Excel的快速开发平台,接下来给大家介绍如何体现这些特点. 一.可视化设计 网页系统的开发,包含UI设计+代码编写的工作,最终形成网页系统.这要求系统开发人员 ...

  3. 自己手写一个SpringMVC 框架

    一.了解SpringMVC运行流程及九大组件 1.SpringMVC 的运行流程   · 用户发送请求至前端控制器DispatcherServlet · DispatcherServlet收到请求调用 ...

  4. 【导航】Python相关

    [博客导航] Python相关导航 [索引]Python常用资源(从新手到大牛) [任务]Python语言程序设计.MOOC学习 [笔记]Python集成开发环境——PyCharm 2018.3下载. ...

  5. .NET CORE学习笔记系列(3)——ASP.NET CORE多环境标识

    在开发项目的过程当中,生产环境与调试环境的配置是不一样的.比如连接字符串. ASP .NET CORE 支持利用环境变量来动态配置 JSON 文件.ASP.NET Core 引用了一个特定的环境变量  ...

  6. KafkaManager编译安装使用(支持kerberos认证)

    为了能够方便的查看及管理Kafka集群,yahoo提供了一个基于Web的管理工具(Kafka-Manager). 这个工具可以方便的查看集群中Kafka的Topic的状态(分区.副本及消息量等),支持 ...

  7. 解决Error response from daemon: Get https://registry-1.docker.io/v2/library/hello-world/manifests/

    https://blog.csdn.net/quanqxj/article/details/79479943

  8. 10分钟,AppCan帮你搞定跨平台开发APP问题!

    跨平台开发APP时,开发者总会遇到一些问题,如打包失败等等,尤其对于iOS来说,由于它的限制性会导致一些状况发生(如证书上传问题等),小编总结了几个AppCan在线IOS打包失败常见的情况及排查技巧, ...

  9. java中的out of memory

    转:http://outofmemory.cn/c/java-outOfMemoryError java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的 ...

  10. js获取浏览器窗体最大化事件

    <mce:script language="javascript"><!--function ReSet() {document.getElementById(& ...