【CF1252L】Road Construction(基环树,最大流)
题意:给定一张n点n边无重边自环的无向图,刚开始每条边都没有被选择,每条边上有一个颜色集合,必须从中选择一种
有K个工人,每个工人有颜色a[i],需要把工人分配到与其颜色相同的边上
问是否能有一种使得n个点完全联通的方案,如果有则输出
n,K<=2000
思路:考虑n-1条边的树的弱化版,显然每条边都应该被选择,用颜色和边建图跑最大流即可
n点n边的基环树的情况下需要把环抠出来,设环的大小为size,两个端点至少有一个在环中的为A集合,其余为B集合
显然B集合中所有的边都需要被选取,A集合中至多只能选择size-1条
可以另外加源或者汇限制A集合的流量,也可以先加入B集合中的所有边,先跑最大流,判断是否小于n-size,因为A集合至多只有size-1的流量
两种方法都试过,都很快
我猜题解里写的应该就是用最大流跑的匹配,没听说过有能跑这个多重匹配的新算法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,ll>P;
#define N 200010
#define M 1000000
#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1
#define fors(i) for(auto i:e[x]) if(i!=p) const int MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int dx[]={-,,,};
int dy[]={,,-,}; int head[N],vet[N],len[N],nxt[N],inq[N],inc[N],a[N],
flag[N],vis[N],stk[N],dis[N],p[N],c[N],match[N],
tot,top,s,S,T,T1; VI b[N],co[N]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} ll readll()
{
ll v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void add(int a,int b)
{
nxt[++tot]=head[a];
vet[tot]=b;
head[a]=tot;
} void Add(int a,int b,int c)
{
nxt[++tot]=head[a];
vet[tot]=b;
len[tot]=c;
head[a]=tot; nxt[++tot]=head[b];
vet[tot]=a;
len[tot]=;
head[b]=tot;
} void findc(int u,int fa)
{
stk[++top]=u;
inq[u]=vis[u]=;
int e=head[u];
while(e)
{
int v=vet[e];
if(!vis[v]) findc(v,u);
else if(v!=fa&&inq[v])
{
int s=,t=top;
while()
{
t--;
s++;
if(stk[t]==v) break;
}
if(s>=)
{
t=top;
while()
{
inc[stk[t]]=;
t--;
if(stk[t]==v){inc[v]=; break;}
} }
}
e=nxt[e];
}
inq[stk[top]]=;
top--;
} int bfs()
{
queue<int> q;
rep(i,,s) dis[i]=-;
q.push(S),dis[S]=;
while(!q.empty())
{
int u=q.front();
q.pop();
int e=head[u];
while(e)
{
int v=vet[e];
if(len[e]&&dis[v]==-)
{
dis[v]=dis[u]+;
q.push(v);
}
e=nxt[e];
}
}
return dis[T]!=-;
} int dfs(int u,int aug)
{
if(u==T) return aug;
int e=head[u],val=,flow=;
while(e)
{
int v=vet[e];
if(len[e]&&dis[v]==dis[u]+)
{
int t=dfs(v,min(len[e],aug));
if(!t)
{
e=nxt[e];
continue;
}
flow+=t;
aug-=t;
len[e]-=t;
len[e^]+=t;
if(!aug) break;
}
e=nxt[e];
}
if(!flow) dis[u]=-;
return flow;
} int main()
{
int n=read(),K=read();
int m=;
rep(i,,n)
{
p[i]=read();
int x=read();
while(x--)
{
int y=read();
b[i].pb(y);
c[++m]=y;
}
}
rep(i,,K)
{
a[i]=read();
c[++m]=a[i];
}
sort(c+,c+m+);
int k=unique(c+,c+m+)-c-;
rep(i,,n)
for(int j=;j<b[i].size();j++) b[i][j]=lower_bound(c+,c+k+,b[i][j])-c; rep(i,,k) co[i].clear();
rep(i,,K)
{
a[i]=lower_bound(c+,c+k+,a[i])-c;
co[a[i]].pb(i);
} tot=;
rep(i,,n)
{
add(i,p[i]);
add(p[i],i);
}
findc(,);
s=k+n,S=++s,T=++s;
rep(i,,s) head[i]=;
tot=;
int sz=;
rep(i,,k) Add(S,i,co[i].size());
rep(i,,n)
for(int j=;j<b[i].size();j++) Add(b[i][j],i+k,);
rep(i,,n)
if(inc[i]==||inc[p[i]]==) Add(i+k,T,);
else sz++;
int ans=;
while(bfs()) ans+=dfs(S,INF);
if(ans<(n--(sz-)))
{
printf("-1\n");
return ;
}
rep(i,,n)
if(inc[i]&&inc[p[i]]) Add(i+k,T,);
while(bfs()) ans+=dfs(S,INF);
if(ans<n-) printf("-1\n");
else
{
rep(i,,n) flag[i]=;
rep(i,,k)
{
int e=head[i],j=;
while(e)
{
int v=vet[e];
if(v>=k+&&v<=k+n&&flag[v-k]==&&!len[e])
{
j++;
if(j>(int)co[i].size()) break;
int t=co[i][j-];
match[t]=v-k;
flag[v-k]=;
}
e=nxt[e];
}
}
rep(i,,K) printf("%d %d\n",match[i],p[match[i]]);
} return ;
}
【CF1252L】Road Construction(基环树,最大流)的更多相关文章
- POJ3352 Road Construction (双连通分量)
Road Construction Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
- POJ P3352 Road Construction 解题报告
P3352 Road Construction 描述 这几乎是夏季,这意味着它几乎是夏季施工时间!今年,负责岛屿热带岛屿天堂道路的优秀人士,希望修复和升级岛上各个旅游景点之间的各种道路. 道路本身也很 ...
- [POJ3352]Road Construction
[POJ3352]Road Construction 试题描述 It's almost summer time, and that means that it's almost summer cons ...
- POJ3352 Road Construction(边双连通分量)
...
- poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】
Road Construction Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10141 Accepted: 503 ...
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...
- 【BZOJ1791】【IOI2008】【基环树】island(status第一速度)
1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 908 Solved: 159 [Su ...
- POJ3352 Road Construction 双连通分量+缩点
Road Construction Description It's almost summer time, and that means that it's almost summer constr ...
- 【Tarjan缩点】PO3352 Road Construction
Road Construction Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 12532 Accepted: 630 ...
随机推荐
- python 并发编程 多进程 生产者消费者模型总结
生产者消费者模型总结 生产者消费者模型什么时候用? 1.程序中有两类角色 一类负责生产数据(生产者) 一类负责处理数据(消费者) 2.引入生产者消费者模型为了解决的问题是 平衡生产者与消费者之间的速度 ...
- 六、Kubernetes_V1.10集群部署-node-部署节点组件
一.配置kubelet 1.配置启动文件 # cat > /usr/lib/systemd/system/kubelet.service <<EOF [Unit] Descripti ...
- Pikachu漏洞练习平台实验——XSS(二)
概述 简介 XSS是一种发生在Web前端的漏洞,所以其危害的对象也主要是前端用户 XSS漏洞可以用来进行钓鱼攻击.前端js挖矿.盗取用户cookie,甚至对主机进行远程控制 攻击流程 假设存在漏洞的是 ...
- linux命令之import
linux下截屏除了printscreen按键外,还可以用improt命令. 该命令最常用的两种方式: 1.鼠标选择范围截屏:import mypicture.jpg 2.截取全屏:import -w ...
- 洛谷 - P3469 - BLO-Blockade - 割点
https://www.luogu.org/problem/P3469 翻译:一个原本连通的无向图,可以删除图中的一个点,求因为删除这个点所导致的不连通的有序点对的数量.或者说,删去这个点之后,各个连 ...
- Flask开发系列之快速入门
Flask开发系列之快速入门 文档 一个最小的应用 调试模式 路由 变量规则 构造 URL HTTP 方法 静态文件 模板渲染 访问请求数据 环境局部变量 请求对象 文件上传 Cookies 重定向和 ...
- apache的rewrite机制
当我们使用thinkphp的时候,比如说我们访问一个Test控制器的test方法,http://localhost/index.php/Test/test/1.html,那个这个1是用get方式传递的 ...
- Qualcomm_Mobile_OpenCL.pdf 翻译-4-Adreno OpenCL的程序开发
这章将简要讨论一些开发Adreno OpenCL应用程序的基本要求,下面将会介绍如何调试和统计程序性能. 4.1 安卓平台上开发OpenCL程序 目前,Adreno GPU主要是在安卓操作系统和在部 ...
- Gcd HDU - 6545 (基础数论)
wls 有一个整数 n,他想将 1 − n 这 n 个数字分成两组,每一组至少有一个数,并且使得两组数字的和的最大公约数最大,请输出最大的最大公约数. Input 输入一行一个整数 n. 2 ≤ n ...
- HDU - 1024 Max Sum Plus Plus 最大m段子段和+滚动数组优化
给定n个数字,求其中m段的最大值(段与段之间不用连续,但是一段中要连续) 例如:2 5 1 -2 2 3 -1五个数字中选2个,选择1和2 3这两段. dp[i][j]从前j个数字中选择i段,然后根据 ...